Subversion Repositories pentevo

Rev

Rev 668 | 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
134 ddp 2
//
3
// generates horizontal sync, blank and video start strobe, horizontal window
668 lvd 4
 
5
/*
6
    This file is part of ZX-Evo Base Configuration firmware.
7
 
8
    ZX-Evo Base Configuration firmware is free software:
9
    you can redistribute it and/or modify it under the terms of
10
    the GNU General Public License as published by
11
    the Free Software Foundation, either version 3 of the License, or
12
    (at your option) any later version.
13
 
14
    ZX-Evo Base Configuration firmware is distributed in the hope that
15
    it will be useful, but WITHOUT ANY WARRANTY; without even
16
    the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
    See the GNU General Public License for more details.
18
 
19
    You should have received a copy of the GNU General Public License
20
    along with ZX-Evo Base Configuration firmware.
21
    If not, see <http://www.gnu.org/licenses/>.
22
*/
23
 
134 ddp 24
//
25
// =\                  /=========||...
26
// ==\                /==========||...
27
// ====---     -------===========||...
28
//    |  \   / |      |
29
//    |   ---  |      |
30
//    |  |   | |      |
31
//    0  t1  | t3     t4
32
//           t2
33
// at 0, video ends and blank begins
34
//    t1 = 10 clocks (@7MHz), sync begins
35
// t2-t1 = 33 clocks
36
// t3-t2 = 41 clocks, then video starts
37
//
38
// repetition period = 448 clocks
39
 
668 lvd 40
`include "../include/tune.v"
134 ddp 41
 
317 lvd 42
module video_sync_h(
134 ddp 43
 
282 lvd 44
        input  wire        clk,
134 ddp 45
 
282 lvd 46
        input  wire        init, // one-pulse strobe read at cend==1, initializes phase
47
                                 // this is mainly for phasing with CPU clock 3.5/7 MHz
48
                                 // still not used, but this may change anytime
134 ddp 49
 
282 lvd 50
        input  wire        cend,     // working strobes from DRAM controller (7MHz)
51
        input  wire        pre_cend,
134 ddp 52
 
53
 
354 lvd 54
        // modes inputs
282 lvd 55
        input  wire        mode_atm_n_pent,
354 lvd 56
        input  wire        mode_a_text,
134 ddp 57
 
684 lvd 58
        input  wire [ 1:0] modes_raster,
59
        input  wire        mode_contend_type,
134 ddp 60
 
282 lvd 61
        output reg         hblank,
62
        output reg         hsync,
134 ddp 63
 
282 lvd 64
        output reg         line_start,  // 1 video cycle prior to actual start of visible line
65
        output reg         hsync_start, // 1 cycle prior to beginning of hsync: used in frame sync/blank generation
66
                                        // these signals coincide with cend
134 ddp 67
 
282 lvd 68
        output reg         hint_start, // horizontal position of INT start, for fine tuning
134 ddp 69
 
282 lvd 70
        output reg         scanin_start,
71
 
684 lvd 72
        input  wire        vpix,
318 lvd 73
        output reg         hpix, // marks gate during which pixels are outting
282 lvd 74
 
684 lvd 75
        output reg         contend, // for 48k/128k CPU contention
76
 
77
        output reg         border_sync, // for 48k/128k 4t border emulation
78
 
318 lvd 79
                                        // these signals turn on and turn off 'go' signal
80
        output reg         fetch_start, // 18 cycles earlier than hpix, coincide with cend
81
        output reg         fetch_end    // --//--
82
 
134 ddp 83
);
84
 
85
 
86
        localparam HBLNK_BEG = 9'd00;
87
        localparam HSYNC_BEG = 9'd10;
88
        localparam HSYNC_END = 9'd43;
89
        localparam HBLNK_END = 9'd88;
90
 
282 lvd 91
        // pentagon (x256)
92
        localparam HPIX_BEG_PENT = 9'd140; // 52 cycles from line_start to pixels beginning
93
        localparam HPIX_END_PENT = 9'd396;
134 ddp 94
 
282 lvd 95
        // atm (x320)
96
        localparam HPIX_BEG_ATM = 9'd108; // 52 cycles from line_start to pixels beginning
97
        localparam HPIX_END_ATM = 9'd428;
98
 
99
 
318 lvd 100
        localparam FETCH_FOREGO = 9'd18; // consistent with older go_start in older fetch.v:
101
                                         // actual data starts fetching 2 dram cycles after
102
                                         // 'go' goes to 1, screen output starts another
103
                                         // 16 cycles after 1st data bundle is fetched
104
 
105
 
134 ddp 106
        localparam SCANIN_BEG = 9'd88; // when scan-doubler starts pixel storing
107
 
108
 
684 lvd 109
        localparam HINT_BEG      = 9'd2;
110
        localparam HINT_BEG_48K  = 9'd126;
111
        localparam HINT_BEG_128K = 9'd130;
134 ddp 112
 
113
 
684 lvd 114
        localparam HPERIOD_224 = 9'd448;
115
        localparam HPERIOD_228 = 9'd456;
134 ddp 116
 
684 lvd 117
 
118
        localparam CONTEND_START = 9'd127; // fixed for correct contend phase: coincides with positive edge of z80 clock
119
        //localparam CONTEND_START_48K  = 9'd132;
120
        //localparam CONTEND_START_128K = 9'd132;
121
 
122
 
123
        localparam BORDER_PHASE = 3'd4;
124
 
125
 
134 ddp 126
        reg [8:0] hcount;
127
 
684 lvd 128
        reg [8:0] contend_ctr;
134 ddp 129
 
318 lvd 130
        // for simulation only
131
        //
134 ddp 132
        initial
133
        begin
134
                hcount = 9'd0;
135
                hblank = 1'b0;
136
                hsync = 1'b0;
137
                line_start = 1'b0;
138
                hsync_start = 1'b0;
139
                hpix = 1'b0;
140
        end
141
 
318 lvd 142
 
143
 
144
 
134 ddp 145
        always @(posedge clk) if( cend )
146
        begin
684 lvd 147
            if(  init || hcount==( (modes_raster==2'b11) ? (HPERIOD_228-9'd1) : (HPERIOD_224-9'd1) )  )
134 ddp 148
                hcount <= 9'd0;
149
            else
150
                hcount <= hcount + 9'd1;
151
        end
152
 
153
 
154
 
155
        always @(posedge clk) if( cend )
156
        begin
157
                if( hcount==HBLNK_BEG )
158
                        hblank <= 1'b1;
159
                else if( hcount==HBLNK_END )
160
                        hblank <= 1'b0;
161
 
162
 
163
                if( hcount==HSYNC_BEG )
164
                        hsync <= 1'b1;
165
                else if( hcount==HSYNC_END )
166
                        hsync <= 1'b0;
167
        end
168
 
169
 
170
        always @(posedge clk)
171
        begin
172
                if( pre_cend )
173
                begin
174
                        if( hcount==HSYNC_BEG )
175
                                hsync_start <= 1'b1;
176
 
177
                        if( hcount==HBLNK_END )
178
                                line_start <= 1'b1;
179
 
180
                        if( hcount==SCANIN_BEG )
181
                                scanin_start <= 1'b1;
318 lvd 182
 
134 ddp 183
                end
184
                else
185
                begin
318 lvd 186
                        hsync_start  <= 1'b0;
187
                        line_start   <= 1'b0;
134 ddp 188
                        scanin_start <= 1'b0;
189
                end
190
        end
191
 
192
 
354 lvd 193
 
194
        wire fetch_start_time, fetch_start_condition;
355 lvd 195
        wire fetch_end_condition;
354 lvd 196
 
197
        reg [3:0] fetch_start_wait;
198
 
355 lvd 199
 
200
        assign fetch_start_time = (mode_atm_n_pent                  ?
354 lvd 201
                                  (HPIX_BEG_ATM -FETCH_FOREGO-9'd4) :
355 lvd 202
                                  (HPIX_BEG_PENT-FETCH_FOREGO-9'd4) ) == hcount;
354 lvd 203
 
204
        always @(posedge clk) if( cend )
205
                fetch_start_wait[3:0] <= { fetch_start_wait[2:0], fetch_start_time };
206
 
355 lvd 207
        assign fetch_start_condition = mode_a_text ? fetch_start_time  : fetch_start_wait[3];
354 lvd 208
 
134 ddp 209
        always @(posedge clk)
354 lvd 210
        if( pre_cend && fetch_start_condition )
211
                fetch_start <= 1'b1;
212
        else
213
                fetch_start <= 1'b0;
214
 
215
 
216
 
217
 
355 lvd 218
        assign fetch_end_time = (mode_atm_n_pent             ?
219
                                (HPIX_END_ATM -FETCH_FOREGO) :
220
                                (HPIX_END_PENT-FETCH_FOREGO) ) == hcount;
354 lvd 221
 
222
        always @(posedge clk)
355 lvd 223
        if( pre_cend && fetch_end_time )
224
                fetch_end <= 1'b1;
225
        else
226
                fetch_end <= 1'b0;
227
 
228
 
229
 
230
 
231
 
232
        always @(posedge clk)
134 ddp 233
        begin
684 lvd 234
                if( pre_cend && hcount==( modes_raster[1] ? (modes_raster[0] ? HINT_BEG_128K : HINT_BEG_48K) : HINT_BEG ) )
134 ddp 235
                        hint_start <= 1'b1;
236
                else
237
                        hint_start <= 1'b0;
238
        end
239
 
240
 
241
        always @(posedge clk) if( cend )
242
        begin
282 lvd 243
                if( hcount==(mode_atm_n_pent ? HPIX_BEG_ATM : HPIX_BEG_PENT) )
134 ddp 244
                        hpix <= 1'b1;
282 lvd 245
                else if( hcount==(mode_atm_n_pent ? HPIX_END_ATM : HPIX_END_PENT) )
134 ddp 246
                        hpix <= 1'b0;
247
        end
248
 
249
 
318 lvd 250
 
684 lvd 251
        // contention generator
252
        initial
253
                contend_ctr <=9'h100;
254
        //
255
        always @(posedge clk) if( cend )
256
        begin
257
                if( hcount == CONTEND_START )
258
                        contend_ctr <= 9'd0;
259
                else if( !contend_ctr[8] )
260
                        contend_ctr <= contend_ctr + 9'd1;
261
        end
262
        //
263
        //
264
        always @(posedge clk) if( cend )
265
        begin
266
                if( contend_ctr[8] || !vpix )
267
                        contend <= 1'b0;
268
                else if( !mode_contend_type )
269
                // 48k type contention
270
                case( contend_ctr[3:1] )
271
                        3'd6,
272
                        3'd7:    contend <= 1'b0;
273
                        default: contend <= 1'b1;
274
                endcase
275
                else
276
                // +2a/+3 type contention
277
                case( contend_ctr[3:1] )
278
                        3'd1:    contend <= 1'b0;
279
                        default: contend <= 1'b1;
280
                endcase
281
                //
282
                // warning! probably +2a/+3 contention pattern is incorrect, it begins with 1 cycle contention but probably should end
283
                //  with one extra contention cycle. Anyway this is left as TODO.
284
                //
285
        end
318 lvd 286
 
287
 
684 lvd 288
 
289
        // border sync signal gen
290
        always @(posedge clk)
291
        if( pre_cend && hcount[2:0]==BORDER_PHASE )
292
                border_sync <= 1'b1;
293
        else
294
                border_sync <= 1'b0;
295
 
296
 
297
 
134 ddp 298
endmodule
299