OpenCores
URL https://opencores.org/ocsvn/aoocs/aoocs/trunk

Subversion Repositories aoocs

[/] [aoocs/] [trunk/] [rtl/] [ocs_video.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without modification, are
5
 * permitted provided that the following conditions are met:
6
 *
7
 *  1. Redistributions of source code must retain the above copyright notice, this list of
8
 *     conditions and the following disclaimer.
9
 *
10
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
11
 *     of conditions and the following disclaimer in the documentation and/or other materials
12
 *     provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
 
25
/*! \file
26
 * \brief OCS video implementation with WISHBONE master and slave interface.
27
 */
28
 
29
/*! \brief \copybrief ocs_video.v
30
 
31
List of video registers:
32
\verbatim
33
Implemented:
34
    DIWSTRT      08E  W   A       Display window start (upper left vert-horiz position)
35
    DIWSTOP      090  W   A       Display window stop (lower right vert.-horiz. position)
36
    DDFSTRT      092  W   A       Display bitplane data fetch start (horiz. position)
37
    DDFSTOP      094  W   A       Display bitplane data fetch stop              write implemented here
38
     [DMACON     096  W   ADP     DMA control write (clear or set)              write implemented here]
39
 
40
     [JOY1DAT   *00C  R   D       Joystick-mouse 1 data (vert,horiz)            read not implemented here]
41
    CLXDAT      *00E  R   D       Collision data register (read and clear)      read not implemented here
42
    CLXCON       098  W   D       Collision control                             write implemented here
43
     [INTENA     09A  W   P       Interrupt enable bits (clear or set bits)     write implemented here]
44
 
45
    BPLCON0      100  W   AD( E ) Bitplane control register (misc. control bits)
46
    BPLCON1      102  W   D       Bitplane control reg. (scroll value PF1, PF2)
47
    BPLCON2      104  W   D( E )  Bitplane control reg. (priority control)
48
 
49
    BPL1MOD      108  W   A       Bitplane modulo (odd planes)
50
    BPL2MOD      10A  W   A       Bitplane modulo (even planes)
51
 
52
    BPL1PTH   +  0E0  W   A       Bitplane 1 pointer (high 3 bits)
53
    BPL1PTL   +  0E2  W   A       Bitplane 1 pointer (low 15 bits)
54
    BPL2PTH   +  0E4  W   A       Bitplane 2 pointer (high 3 bits)
55
    BPL2PTL   +  0E6  W   A       Bitplane 2 pointer (low 15 bits)
56
    BPL3PTH   +  0E8  W   A       Bitplane 3 pointer (high 3 bits)
57
    BPL3PTL   +  0EA  W   A       Bitplane 3 pointer (low 15 bits)
58
    BPL4PTH   +  0EC  W   A       Bitplane 4 pointer (high 3 bits)
59
    BPL4PTL   +  0EE  W   A       Bitplane 4 pointer (low 15 bits)
60
    BPL5PTH   +  0F0  W   A       Bitplane 5 pointer (high 3 bits)
61
    BPL5PTL   +  0F2  W   A       Bitplane 5 pointer (low 15 bits)
62
    BPL6PTH   +  0F4  W   A       Bitplane 6 pointer (high 3 bits)
63
    BPL6PTL   +  0F6  W   A       Bitplane 6 pointer (low 15 bits)
64
 
65
    BPL1DAT   &  110  W   D       Bitplane 1 data (parallel-to-serial convert)
66
    BPL2DAT   &  112  W   D       Bitplane 2 data (parallel-to-serial convert)
67
    BPL3DAT   &  114  W   D       Bitplane 3 data (parallel-to-serial convert)
68
    BPL4DAT   &  116  W   D       Bitplane 4 data (parallel-to-serial convert)
69
    BPL5DAT   &  118  W   D       Bitplane 5 data (parallel-to-serial convert)
70
    BPL6DAT   &  11A  W   D       Bitplane 6 data (parallel-to-serial convert)
71
 
72
    SPR0PTH   +  120  W   A       Sprite 0 pointer (high 3 bits)
73
    SPR0PTL   +  122  W   A       Sprite 0 pointer (low 15 bits)
74
    SPR0POS   %  140  W   AD      Sprite 0 vert-horiz start position data
75
    SPR0CTL   %  142  W   AD( E ) Sprite 0 vert stop position and control data
76
    SPR0DATA  %  144  W   D       Sprite 0 image data register A
77
    SPR0DATB  %  146  W   D       Sprite 0 image data register B
78
    SPR1PTH   +  124  W   A       Sprite 1 pointer (high 3 bits)
79
    SPR1PTL   +  126  W   A       Sprite 1 pointer (low 15 bits)
80
    SPR1POS   %  148  W   AD      Sprite 1 vert-horiz start position  data
81
    SPR1CTL   %  14A  W   AD      Sprite 1 vert stop position and control data
82
    SPR1DATA  %  14C  W   D       Sprite 1 image data register A
83
    SPR1DATB  %  14E  W   D       Sprite 1 image data register B
84
    SPR2PTH   +  128  W   A       Sprite 2 pointer (high 3 bits)
85
    SPR2PTL   +  12A  W   A       Sprite 2 pointer (low 15 bits)
86
    SPR2POS   %  150  W   AD      Sprite 2 vert-horiz start position data
87
    SPR2CTL   %  152  W   AD      Sprite 2 vert stop position and control data
88
    SPR2DATA  %  154  W   D       Sprite 2 image data register A
89
    SPR2DATB  %  156  W   D       Sprite 2 image data register B
90
    SPR3PTH   +  12C  W   A       Sprite 3 pointer (high 3 bits)
91
    SPR3PTL   +  12E  W   A       Sprite 3 pointer (low 15 bits)
92
    SPR3POS   %  158  W   AD      Sprite 3 vert-horiz start position data
93
    SPR3CTL   %  15A  W   AD      Sprite 3 vert stop position and control data
94
    SPR3DATA  %  15C  W   D       Sprite 3 image data register A
95
    SPR3DATB  %  15E  W   D       Sprite 3 image data register B
96
    SPR4PTH   +  130  W   A       Sprite 4 pointer (high 3 bits)
97
    SPR4PTL   +  132  W   A       Sprite 4 pointer (low 15 bits)
98
    SPR4POS   %  160  W   AD      Sprite 4 vert-horiz start position data
99
    SPR4CTL   %  162  W   AD      Sprite 4 vert stop position and control data
100
    SPR4DATA  %  164  W   D       Sprite 4 image data register A
101
    SPR4DATB  %  166  W   D       Sprite 4 image data register B
102
    SPR5PTH   +  134  W   A       Sprite 5 pointer (high 3 bits)
103
    SPR5PTL   +  136  W   A       Sprite 5 pointer (low 15 bits)
104
    SPR5POS   %  168  W   AD      Sprite 5 vert-horiz start position data
105
    SPR5CTL   %  16A  W   AD      Sprite 5 vert stop position and control data
106
    SPR5DATA  %  16C  W   D       Sprite 5 image data register A
107
    SPR5DATB  %  16E  W   D       Sprite 5 image data register B
108
    SPR6PTH   +  138  W   A       Sprite 6 pointer (high 3 bits)
109
    SPR6PTL   +  13A  W   A       Sprite 6 pointer (low 15 bits)
110
    SPR6POS   %  170  W   AD      Sprite 6 vert-horiz start position data
111
    SPR6CTL   %  172  W   AD      Sprite 6 vert stop position and control data
112
    SPR6DATA  %  174  W   D       Sprite 6 image data register A
113
    SPR6DATB  %  176  W   D       Sprite 6 image data register B
114
    SPR7PTH   +  13C  W   A       Sprite 7 pointer (high 3 bits)
115
    SPR7PTL   +  13E  W   A       Sprite 7 pointer (low 15 bits)
116
    SPR7POS   %  178  W   AD      Sprite 7 vert-horiz start position data
117
    SPR7CTL   %  17A  W   AD      Sprite 7 vert stop position and control data
118
    SPR7DATA  %  17C  W   D       Sprite 7 image data register A
119
    SPR7DATB  %  17E  W   D       Sprite 7 image data register B
120
 
121
    COLOR00      180  W   D       Color table 00
122
    COLOR01      182  W   D       Color table 01
123
    COLOR02      184  W   D       Color table 02
124
    COLOR03      186  W   D       Color table 03
125
    COLOR04      188  W   D       Color table 04
126
    COLOR05      18A  W   D       Color table 05
127
    COLOR06      18C  W   D       Color table 06
128
    COLOR07      18E  W   D       Color table 07
129
    COLOR08      190  W   D       Color table 08
130
    COLOR09      192  W   D       Color table 09
131
    COLOR10      194  W   D       Color table 10
132
    COLOR11      196  W   D       Color table 11
133
    COLOR12      198  W   D       Color table 12
134
    COLOR13      19A  W   D       Color table 13
135
    COLOR14      19C  W   D       Color table 14
136
    COLOR15      19E  W   D       Color table 15
137
    COLOR16      1A0  W   D       Color table 16
138
    COLOR17      1A2  W   D       Color table 17
139
    COLOR18      1A4  W   D       Color table 18
140
    COLOR19      1A6  W   D       Color table 19
141
    COLOR20      1A8  W   D       Color table 20
142
    COLOR21      1AA  W   D       Color table 21
143
    COLOR22      1AC  W   D       Color table 22
144
    COLOR23      1AE  W   D       Color table 23
145
    COLOR24      1B0  W   D       Color table 24
146
    COLOR25      1B2  W   D       Color table 25
147
    COLOR26      1B4  W   D       Color table 26
148
    COLOR27      1B6  W   D       Color table 27
149
    COLOR28      1B8  W   D       Color table 28
150
    COLOR29      1BA  W   D       Color table 29
151
    COLOR30      1BC  W   D       Color table 30
152
    COLOR31      1BE  W   D       Color table 31
153
\endverbatim
154
*/
155
module ocs_video(
156
    //% \name Clock and reset
157
    //% @{
158
    input               CLK_I,
159
    input               reset_n,
160
    //% @}
161
 
162
    //% \name WISHBONE master
163
    //% @{
164
    output reg          CYC_O,
165
    output reg          STB_O,
166
    output              WE_O,
167
    output reg [31:2]   ADR_O,
168
    output [3:0]        SEL_O,
169
    input [31:0]        master_DAT_I,
170
    input               ACK_I,
171
    //% @}
172
 
173
    //% \name WISHBONE slave
174
    //% @{
175
    input               CYC_I,
176
    input               STB_I,
177
    input               WE_I,
178
    input [8:2]         ADR_I,
179
    input [3:0]         SEL_I,
180
    input [31:0]        slave_DAT_I,
181
    output reg          ACK_O,
182
    //% @}
183
 
184
    //% \name Not aligned register access on a 32-bit WISHBONE bus
185
    //% @{
186
        // CLXDAT read not implemented here
187
    input               na_clx_dat_read,
188
    output [15:0]       na_clx_dat,
189
        // INTENA write implemented here
190
    output              na_int_ena_write,
191
    output [15:0]       na_int_ena,
192
    output [1:0]        na_int_ena_sel,
193
        // DMACON write implemented here
194
    output              na_dma_con_write,
195
    output [15:0]       na_dma_con,
196
    output [1:0]        na_dma_con_sel,
197
    //% @}
198
 
199
    //% \name Direct drv_ssram read/write DMA burst video interface
200
    //% @{
201
        // bitplain burst read
202
        output              burst_read_request,
203
        output [31:2]       burst_read_address,
204
        input               burst_read_ready,
205
        input [31:0]        burst_read_data,
206
 
207
    // video output burst write
208
    output              burst_write_request,
209
    output [31:2]       burst_write_address,
210
    output [35:0]       burst_write_data,
211
    input               burst_write_ready,
212
    //% @}
213
 
214
    //% \name Internal OCS ports
215
    //% @{
216
    input               line_start,
217
    input               line_pre_start,
218
    input [8:0]         line_number,
219
    input [8:0]         column_number,
220
 
221
    input [10:0]        dma_con
222
    //% @}
223
);
224
 
225
`define VIDEO_BUFFER            32'h10180000
226
`define VIDEO_BUFFER_DIV_4      30'h04060000
227
 
228
// No: BPLCON0: External synchronize, Lace mode, lightpen, genlock audio enable, color composite
229
// No: data fetch word after word - all fetched at once
230
 
231
/*                              16-bit      32-bit
232
- get sprite data:              2x8         2x8
233
- get bitplain data:            40x6        21x6
234
- save line to video memory:    214         214
235
16-bit: 16+240+214 = 470 = 7.834 us
236
32-bit: 16+126+640+214 = 996 = 16599.993 us
237
 
238
PAL: 52.000 us / 64.000 us
239
display out: 3.567 us / 26.667 us
240
*/
241
assign na_int_ena_write = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && { ADR_I, 2'b0 } == 9'h098 && ACK_O == 1'b0);
242
assign na_int_ena = slave_DAT_I[15:0];
243
assign na_int_ena_sel = SEL_I[1:0];
244
 
245
assign na_dma_con_write = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && { ADR_I, 2'b0 } == 9'h094 && ACK_O == 1'b0);
246
assign na_dma_con = slave_DAT_I[15:0];
247
assign na_dma_con_sel = SEL_I[1:0];
248
 
249
assign SEL_O = 4'b1111;
250
assign WE_O = 1'b0;
251
 
252
wire [3:0] dma_select;
253
assign dma_select =
254
    (sprite0_dma_req == 1'b1) ? 4'd1 :
255
    (sprite1_dma_req == 1'b1) ? 4'd2 :
256
    (sprite2_dma_req == 1'b1) ? 4'd3 :
257
    (sprite3_dma_req == 1'b1) ? 4'd4 :
258
    (sprite4_dma_req == 1'b1) ? 4'd5 :
259
    (sprite5_dma_req == 1'b1) ? 4'd6 :
260
    (sprite6_dma_req == 1'b1) ? 4'd7 :
261
    (sprite7_dma_req == 1'b1) ? 4'd8 :
262
    4'd0;
263
 
264
wire [31:2] dma_address_select;
265
assign dma_address_select =
266
    (dma_select == 4'd1) ? sprite0_dma_address :
267
    (dma_select == 4'd2) ? sprite1_dma_address :
268
    (dma_select == 4'd3) ? sprite2_dma_address :
269
    (dma_select == 4'd4) ? sprite3_dma_address :
270
    (dma_select == 4'd5) ? sprite4_dma_address :
271
    (dma_select == 4'd6) ? sprite5_dma_address :
272
    (dma_select == 4'd7) ? sprite6_dma_address :
273
    sprite7_dma_address;
274
 
275
wire [5:0] bpl_color;
276
wire [1:0] sprite0_color;
277
wire [1:0] sprite1_color;
278
wire sprite01_attached;
279
wire [1:0] sprite2_color;
280
wire [1:0] sprite3_color;
281
wire sprite23_attached;
282
wire [1:0] sprite4_color;
283
wire [1:0] sprite5_color;
284
wire sprite45_attached;
285
wire [1:0] sprite6_color;
286
wire [1:0] sprite7_color;
287
wire sprite67_attached;
288
wire [10:0] bpl_con0;
289
wire window_line_enable;
290
 
291
wire priority_write_ena;
292
assign priority_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
293
    (   ({ ADR_I, 2'b0 } >= 9'h180 && { ADR_I, 2'b0 } <= 9'h1BC) ||
294
        { ADR_I, 2'b0 } == 9'h08C || { ADR_I, 2'b0 } == 9'h090 || { ADR_I, 2'b0 } == 9'h098 || { ADR_I, 2'b0 } == 9'h104
295
    ));
296
 
297
video_priority video_priority_inst (
298
    .CLK_I(CLK_I),
299
    .reset_n(reset_n),
300
 
301
    .line_start(line_start),
302
    .line_pre_start(line_pre_start),
303
    .line_number(line_number),
304
    .column_number(column_number),
305
    .window_line_enable(window_line_enable),
306
 
307
    .write_ena(priority_write_ena),
308
    // 0:   COLOR00,    COLOR01,
309
    // 1:   COLOR02,    COLOR03,
310
    // 2:   COLOR04,    COLOR05,
311
    // 3:   COLOR06,    COLOR07,
312
    // 4:   COLOR08,    COLOR09,
313
    // 5:   COLOR10,    COLOR11,
314
    // 6:   COLOR12,    COLOR13,
315
    // 7:   COLOR14,    COLOR15,
316
    // 8:   COLOR16,    COLOR17,
317
    // 9:   COLOR18,    COLOR19,
318
    // 10:  COLOR20,    COLOR21,
319
    // 11:  COLOR22,    COLOR23,
320
    // 12:  COLOR24,    COLOR25,
321
    // 13:  COLOR26,    COLOR27,
322
    // 14:  COLOR28,    COLOR29,
323
    // 15:  COLOR30,    COLOR31,
324
    // 16:      DIWSTRT [15:0],     COPINS      [31:16], * COPINS not implemented  
325
    // 17:      DIWSTOP [31:16],    DDFSTART    [15:0], *
326
    // 18:      CLXCON  [31:16],    INTENA      [15:0], *
327
    // 19:      BPLCON2 [31:16],    NOT USED    [15:0],
328
    // read:    CLXDAT  [15:0],     JOY1DAT     [31:16] *
329
    .write_address(
330
        ({ ADR_I, 2'b0 } == 9'h180) ? 5'd0 :
331
        ({ ADR_I, 2'b0 } == 9'h184) ? 5'd1 :
332
        ({ ADR_I, 2'b0 } == 9'h188) ? 5'd2 :
333
        ({ ADR_I, 2'b0 } == 9'h18C) ? 5'd3 :
334
        ({ ADR_I, 2'b0 } == 9'h190) ? 5'd4 :
335
        ({ ADR_I, 2'b0 } == 9'h194) ? 5'd5 :
336
        ({ ADR_I, 2'b0 } == 9'h198) ? 5'd6 :
337
        ({ ADR_I, 2'b0 } == 9'h19C) ? 5'd7 :
338
        ({ ADR_I, 2'b0 } == 9'h1A0) ? 5'd8 :
339
        ({ ADR_I, 2'b0 } == 9'h1A4) ? 5'd9 :
340
        ({ ADR_I, 2'b0 } == 9'h1A8) ? 5'd10 :
341
        ({ ADR_I, 2'b0 } == 9'h1AC) ? 5'd11 :
342
        ({ ADR_I, 2'b0 } == 9'h1B0) ? 5'd12 :
343
        ({ ADR_I, 2'b0 } == 9'h1B4) ? 5'd13 :
344
        ({ ADR_I, 2'b0 } == 9'h1B8) ? 5'd14 :
345
        ({ ADR_I, 2'b0 } == 9'h1BC) ? 5'd15 :
346
        ({ ADR_I, 2'b0 } == 9'h08C) ? 5'd16 :
347
        ({ ADR_I, 2'b0 } == 9'h090) ? 5'd17 :
348
        ({ ADR_I, 2'b0 } == 9'h098) ? 5'd18 :
349
        5'd19
350
    ),
351
    .write_data(slave_DAT_I),
352
    .write_sel(SEL_I),
353
 
354
    .bpl_color(bpl_color),
355
    .sprite0_color(sprite0_color),
356
    .sprite1_color(sprite1_color),
357
    .sprite01_attached(sprite01_attached),
358
    .sprite2_color(sprite2_color),
359
    .sprite3_color(sprite3_color),
360
    .sprite23_attached(sprite23_attached),
361
    .sprite4_color(sprite4_color),
362
    .sprite5_color(sprite5_color),
363
    .sprite45_attached(sprite45_attached),
364
    .sprite6_color(sprite6_color),
365
    .sprite7_color(sprite7_color),
366
    .sprite67_attached(sprite67_attached),
367
 
368
    .clx_dat_read(na_clx_dat_read),
369
    .clx_dat(na_clx_dat),
370
 
371
    .bpl_con0(bpl_con0),
372
 
373
    // video interface
374
    .burst_write_request(burst_write_request),
375
    .burst_write_address(burst_write_address),
376
    .burst_write_data(burst_write_data),
377
    .burst_write_ready(burst_write_ready)
378
);
379
 
380
wire bitplains_write_ena;
381
assign bitplains_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
382
    (   ({ ADR_I, 2'b0 } >= 9'h0E0 && { ADR_I, 2'b0 } <= 9'h0F4) ||
383
        { ADR_I, 2'b0 } == 9'h090 ||
384
        { ADR_I, 2'b0 } == 9'h094 ||
385
        { ADR_I, 2'b0 } == 9'h100 ||
386
        { ADR_I, 2'b0 } == 9'h108 ||
387
        ({ ADR_I, 2'b0 } >= 9'h110 && { ADR_I, 2'b0 } <= 9'h118)
388
    ));
389
 
390
wire [7:0] disabled_sprites;
391
 
392
bitplains bitplains_inst(
393
    .CLK_I(CLK_I),
394
    .reset_n(reset_n),
395
 
396
    .line_start(line_start),
397
    .column_number(column_number),
398
 
399
    // video interface - read
400
    .burst_read_enabled(dma_con[9] == 1'b1 && dma_con[8] == 1'b1 && window_line_enable == 1'b1),
401
        .burst_read_request(burst_read_request),
402
        .burst_read_address(burst_read_address),
403
        .burst_read_ready(burst_read_ready),
404
        .burst_read_data(burst_read_data),
405
 
406
    .write_ena(bitplains_write_ena),
407
    // 0:   BPL1PTH,    BPL1PTL,
408
    // 1:   BPL2PTH,    BPL2PTL,
409
    // 2:   BPL3PTH,    BPL3PTL,
410
    // 3:   BPL4PTH,    BPL4PTL,
411
    // 4:   BPL5PTH,    BPL5PTL,
412
    // 5:   BPL6PTH,    BPL6PTL,
413
    // 6:       DDFSTRT [15:0],     DIWSTOP [31:16], *
414
    // 7:       DDFSTOP [31:16],    DMACON  [15:0], *
415
    // 8:   BPLCON0,    BPLCON1,
416
    // 9:   BPL1MOD,    BPL2MOD,
417
    // 10:  BPL1DAT,    BPL2DAT,
418
    // 11:  BPL3DAT,    BPL4DAT,
419
    // 12:  BPL5DAT,    BPL6DAT
420
    .write_address(
421
        ({ ADR_I, 2'b0 } == 9'h0E0) ? 4'd0 :
422
        ({ ADR_I, 2'b0 } == 9'h0E4) ? 4'd1 :
423
        ({ ADR_I, 2'b0 } == 9'h0E8) ? 4'd2 :
424
        ({ ADR_I, 2'b0 } == 9'h0EC) ? 4'd3 :
425
        ({ ADR_I, 2'b0 } == 9'h0F0) ? 4'd4 :
426
        ({ ADR_I, 2'b0 } == 9'h0F4) ? 4'd5 :
427
        ({ ADR_I, 2'b0 } == 9'h090) ? 4'd6 :
428
        ({ ADR_I, 2'b0 } == 9'h094) ? 4'd7 :
429
        ({ ADR_I, 2'b0 } == 9'h100) ? 4'd8 :
430
        ({ ADR_I, 2'b0 } == 9'h108) ? 4'd9 :
431
        ({ ADR_I, 2'b0 } == 9'h110) ? 4'd10 :
432
        ({ ADR_I, 2'b0 } == 9'h114) ? 4'd11 :
433
        4'd12
434
    ),
435
    .write_data(slave_DAT_I),
436
    .write_sel(SEL_I),
437
 
438
    .disable_sprites(disabled_sprites),
439
    .bpl_con0(bpl_con0),
440
    .color(bpl_color),
441
 
442
    .line_number(line_number)
443
);
444
 
445
wire sprite0_write_ena;
446
wire sprite0_dma_req;
447
wire [31:2] sprite0_dma_address;
448
 
449
assign sprite0_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
450
    ({ ADR_I, 2'b0 } == 9'h120 || { ADR_I, 2'b0 } == 9'h140 || { ADR_I, 2'b0 } == 9'h144) );
451
 
452
sprite sprite0_inst(
453
    .CLK_I(CLK_I),
454
    .reset_n(reset_n),
455
 
456
    .line_start(line_start),
457
    .line_number(line_number),
458
    .column_number(column_number),
459
 
460
    .dma_ena(dma_con[9] == 1'b1 && dma_con[5] == 1'b1 && disabled_sprites[0] == 1'b0),
461
    .dma_req(sprite0_dma_req),
462
    .dma_address(sprite0_dma_address),
463
    .dma_done(dma_select == 4'd1 && ACK_I == 1'b1),
464
    .dma_data(master_DAT_I),
465
 
466
    .write_ena(sprite0_write_ena),
467
    // 0:   SPR0PTH,    SPR0PTL,
468
    // 1:   SPR0POS,    SPR0CTL,
469
    // 2:   SPR0DATA,   SPR0DATB,
470
    .write_address(
471
        ({ ADR_I, 2'b0 } == 9'h120) ? 2'd0 :
472
        ({ ADR_I, 2'b0 } == 9'h140) ? 2'd1 :
473
        2'd2
474
    ),
475
    .write_data(slave_DAT_I),
476
    .write_sel(SEL_I),
477
 
478
    .attached(),
479
    .color(sprite0_color)
480
);
481
 
482
wire sprite1_write_ena;
483
wire sprite1_dma_req;
484
wire [31:2] sprite1_dma_address;
485
 
486
assign sprite1_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
487
    ({ ADR_I, 2'b0 } == 9'h124 || { ADR_I, 2'b0 } == 9'h148 || { ADR_I, 2'b0 } == 9'h14C) );
488
 
489
sprite sprite1_inst(
490
    .CLK_I(CLK_I),
491
    .reset_n(reset_n),
492
 
493
    .line_start(line_start),
494
    .line_number(line_number),
495
    .column_number(column_number),
496
 
497
    .dma_ena(dma_con[9] == 1'b1 && dma_con[5] == 1'b1 && disabled_sprites[1] == 1'b0),
498
    .dma_req(sprite1_dma_req),
499
    .dma_address(sprite1_dma_address),
500
    .dma_done(dma_select == 4'd2 && ACK_I == 1'b1),
501
    .dma_data(master_DAT_I),
502
 
503
    .write_ena(sprite1_write_ena),
504
    // 0:   SPR0PTH,    SPR0PTL,
505
    // 1:   SPR0POS,    SPR0CTL,
506
    // 2:   SPR0DATA,   SPR0DATB,
507
    .write_address(
508
        ({ ADR_I, 2'b0 } == 9'h124) ? 2'd0 :
509
        ({ ADR_I, 2'b0 } == 9'h148) ? 2'd1 :
510
        2'd2
511
    ),
512
    .write_data(slave_DAT_I),
513
    .write_sel(SEL_I),
514
 
515
    .attached(sprite01_attached),
516
    .color(sprite1_color)
517
);
518
 
519
wire sprite2_write_ena;
520
wire sprite2_dma_req;
521
wire [31:2] sprite2_dma_address;
522
 
523
assign sprite2_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
524
    ({ ADR_I, 2'b0 } == 9'h128 || { ADR_I, 2'b0 } == 9'h150 || { ADR_I, 2'b0 } == 9'h154) );
525
 
526
sprite sprite2_inst(
527
    .CLK_I(CLK_I),
528
    .reset_n(reset_n),
529
 
530
    .line_start(line_start),
531
    .line_number(line_number),
532
    .column_number(column_number),
533
 
534
    .dma_ena(dma_con[9] == 1'b1 && dma_con[5] == 1'b1 && disabled_sprites[2] == 1'b0),
535
    .dma_req(sprite2_dma_req),
536
    .dma_address(sprite2_dma_address),
537
    .dma_done(dma_select == 4'd3 && ACK_I == 1'b1),
538
    .dma_data(master_DAT_I),
539
 
540
    .write_ena(sprite2_write_ena),
541
    // 0:   SPR0PTH,    SPR0PTL,
542
    // 1:   SPR0POS,    SPR0CTL,
543
    // 2:   SPR0DATA,   SPR0DATB,
544
    .write_address(
545
        ({ ADR_I, 2'b0 } == 9'h128) ? 2'd0 :
546
        ({ ADR_I, 2'b0 } == 9'h150) ? 2'd1 :
547
        2'd2
548
    ),
549
    .write_data(slave_DAT_I),
550
    .write_sel(SEL_I),
551
 
552
    .attached(),
553
    .color(sprite2_color)
554
);
555
 
556
wire sprite3_write_ena;
557
wire sprite3_dma_req;
558
wire [31:2] sprite3_dma_address;
559
 
560
assign sprite3_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
561
    ({ ADR_I, 2'b0 } == 9'h12C || { ADR_I, 2'b0 } == 9'h158 || { ADR_I, 2'b0 } == 9'h15C) );
562
 
563
sprite sprite3_inst(
564
    .CLK_I(CLK_I),
565
    .reset_n(reset_n),
566
 
567
    .line_start(line_start),
568
    .line_number(line_number),
569
    .column_number(column_number),
570
 
571
    .dma_ena(dma_con[9] == 1'b1 && dma_con[5] == 1'b1 && disabled_sprites[3] == 1'b0),
572
    .dma_req(sprite3_dma_req),
573
    .dma_address(sprite3_dma_address),
574
    .dma_done(dma_select == 4'd4 && ACK_I == 1'b1),
575
    .dma_data(master_DAT_I),
576
 
577
    .write_ena(sprite3_write_ena),
578
    // 0:   SPR0PTH,    SPR0PTL,
579
    // 1:   SPR0POS,    SPR0CTL,
580
    // 2:   SPR0DATA,   SPR0DATB,
581
    .write_address(
582
        ({ ADR_I, 2'b0 } == 9'h12C) ? 2'd0 :
583
        ({ ADR_I, 2'b0 } == 9'h158) ? 2'd1 :
584
        2'd2
585
    ),
586
    .write_data(slave_DAT_I),
587
    .write_sel(SEL_I),
588
 
589
    .attached(sprite23_attached),
590
    .color(sprite3_color)
591
);
592
 
593
wire sprite4_write_ena;
594
wire sprite4_dma_req;
595
wire [31:2] sprite4_dma_address;
596
 
597
assign sprite4_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
598
    ({ ADR_I, 2'b0 } == 9'h130 || { ADR_I, 2'b0 } == 9'h160 || { ADR_I, 2'b0 } == 9'h164) );
599
 
600
sprite sprite4_inst(
601
    .CLK_I(CLK_I),
602
    .reset_n(reset_n),
603
 
604
    .line_start(line_start),
605
    .line_number(line_number),
606
    .column_number(column_number),
607
 
608
    .dma_ena(dma_con[9] == 1'b1 && dma_con[5] == 1'b1 && disabled_sprites[4] == 1'b0),
609
    .dma_req(sprite4_dma_req),
610
    .dma_address(sprite4_dma_address),
611
    .dma_done(dma_select == 4'd5 && ACK_I == 1'b1),
612
    .dma_data(master_DAT_I),
613
 
614
    .write_ena(sprite4_write_ena),
615
    // 0:   SPR0PTH,    SPR0PTL,
616
    // 1:   SPR0POS,    SPR0CTL,
617
    // 2:   SPR0DATA,   SPR0DATB,
618
    .write_address(
619
        ({ ADR_I, 2'b0 } == 9'h130) ? 2'd0 :
620
        ({ ADR_I, 2'b0 } == 9'h160) ? 2'd1 :
621
        2'd2
622
    ),
623
    .write_data(slave_DAT_I),
624
    .write_sel(SEL_I),
625
 
626
    .attached(),
627
    .color(sprite4_color)
628
);
629
 
630
wire sprite5_write_ena;
631
wire sprite5_dma_req;
632
wire [31:2] sprite5_dma_address;
633
 
634
assign sprite5_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
635
    ({ ADR_I, 2'b0 } == 9'h134 || { ADR_I, 2'b0 } == 9'h168 || { ADR_I, 2'b0 } == 9'h16C) );
636
 
637
sprite sprite5_inst(
638
    .CLK_I(CLK_I),
639
    .reset_n(reset_n),
640
 
641
    .line_start(line_start),
642
    .line_number(line_number),
643
    .column_number(column_number),
644
 
645
    .dma_ena(dma_con[9] == 1'b1 && dma_con[5] == 1'b1 && disabled_sprites[5] == 1'b0),
646
    .dma_req(sprite5_dma_req),
647
    .dma_address(sprite5_dma_address),
648
    .dma_done(dma_select == 4'd6 && ACK_I == 1'b1),
649
    .dma_data(master_DAT_I),
650
 
651
    .write_ena(sprite5_write_ena),
652
    // 0:   SPR0PTH,    SPR0PTL,
653
    // 1:   SPR0POS,    SPR0CTL,
654
    // 2:   SPR0DATA,   SPR0DATB,
655
    .write_address(
656
        ({ ADR_I, 2'b0 } == 9'h134) ? 2'd0 :
657
        ({ ADR_I, 2'b0 } == 9'h168) ? 2'd1 :
658
        2'd2
659
    ),
660
    .write_data(slave_DAT_I),
661
    .write_sel(SEL_I),
662
 
663
    .attached(sprite45_attached),
664
    .color(sprite5_color)
665
);
666
 
667
wire sprite6_write_ena;
668
wire sprite6_dma_req;
669
wire [31:2] sprite6_dma_address;
670
 
671
assign sprite6_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
672
    ({ ADR_I, 2'b0 } == 9'h138 || { ADR_I, 2'b0 } == 9'h170 || { ADR_I, 2'b0 } == 9'h174) );
673
 
674
sprite sprite6_inst(
675
    .CLK_I(CLK_I),
676
    .reset_n(reset_n),
677
 
678
    .line_start(line_start),
679
    .line_number(line_number),
680
    .column_number(column_number),
681
 
682
    .dma_ena(dma_con[9] == 1'b1 && dma_con[5] == 1'b1 && disabled_sprites[6] == 1'b0),
683
    .dma_req(sprite6_dma_req),
684
    .dma_address(sprite6_dma_address),
685
    .dma_done(dma_select == 4'd7 && ACK_I == 1'b1),
686
    .dma_data(master_DAT_I),
687
 
688
    .write_ena(sprite6_write_ena),
689
    // 0:   SPR0PTH,    SPR0PTL,
690
    // 1:   SPR0POS,    SPR0CTL,
691
    // 2:   SPR0DATA,   SPR0DATB,
692
    .write_address(
693
        ({ ADR_I, 2'b0 } == 9'h138) ? 2'd0 :
694
        ({ ADR_I, 2'b0 } == 9'h170) ? 2'd1 :
695
        2'd2
696
    ),
697
    .write_data(slave_DAT_I),
698
    .write_sel(SEL_I),
699
 
700
    .attached(),
701
    .color(sprite6_color)
702
);
703
 
704
wire sprite7_write_ena;
705
wire sprite7_dma_req;
706
wire [31:2] sprite7_dma_address;
707
 
708
assign sprite7_write_ena = (CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0 &&
709
    ({ ADR_I, 2'b0 } == 9'h13C || { ADR_I, 2'b0 } == 9'h178 || { ADR_I, 2'b0 } == 9'h17C) );
710
 
711
sprite sprite7_inst(
712
    .CLK_I(CLK_I),
713
    .reset_n(reset_n),
714
 
715
    .line_start(line_start),
716
    .line_number(line_number),
717
    .column_number(column_number),
718
 
719
    .dma_ena(dma_con[9] == 1'b1 && dma_con[5] == 1'b1 && disabled_sprites[7] == 1'b0),
720
    .dma_req(sprite7_dma_req),
721
    .dma_address(sprite7_dma_address),
722
    .dma_done(dma_select == 4'd8 && ACK_I == 1'b1),
723
    .dma_data(master_DAT_I),
724
 
725
    .write_ena(sprite7_write_ena),
726
    // 0:   SPR0PTH,    SPR0PTL,
727
    // 1:   SPR0POS,    SPR0CTL,
728
    // 2:   SPR0DATA,   SPR0DATB,
729
    .write_address(
730
        ({ ADR_I, 2'b0 } == 9'h13C) ? 2'd0 :
731
        ({ ADR_I, 2'b0 } == 9'h178) ? 2'd1 :
732
        2'd2
733
    ),
734
    .write_data(slave_DAT_I),
735
    .write_sel(SEL_I),
736
 
737
    .attached(sprite67_attached),
738
    .color(sprite7_color)
739
);
740
 
741
always @(posedge CLK_I or negedge reset_n) begin
742
    if(reset_n == 1'b0) begin
743
        CYC_O <= 1'b0;
744
        STB_O <= 1'b0;
745
        ADR_O <= 19'd0;
746
        ACK_O <= 1'b0;
747
    end
748
    else begin
749
        // write/read registers as slave
750
 
751
        // if start of new line:
752
        //      get sprite data as master
753
        //      get bitmap data as master
754
 
755
        // concurrent save line to video memory
756
 
757
        if(ACK_O == 1'b1) begin
758
            ACK_O <= 1'b0;
759
        end
760
        else if((CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b0) || priority_write_ena == 1'b1 || bitplains_write_ena == 1'b1 ||
761
            sprite0_write_ena == 1'b1 || sprite1_write_ena == 1'b1 || sprite2_write_ena == 1'b1 || sprite3_write_ena == 1'b1 ||
762
            sprite4_write_ena == 1'b1 || sprite5_write_ena == 1'b1 || sprite6_write_ena == 1'b1 || sprite7_write_ena == 1'b1 ||
763
            na_int_ena_write == 1'b1 || na_dma_con_write == 1'b1)
764
        begin
765
            ACK_O <= 1'b1;
766
        end
767
 
768
        if(CYC_O == 1'b0 && STB_O == 1'b0 && dma_select != 4'd0) begin
769
            ADR_O <= dma_address_select;
770
            CYC_O <= 1'b1;
771
            STB_O <= 1'b1;
772
        end
773
        else if(CYC_O == 1'b1 && STB_O == 1'b1 && ACK_I == 1'b1) begin
774
            CYC_O <= 1'b0;
775
            STB_O <= 1'b0;
776
        end
777
 
778
        // WARNING: disable sprites if ddf_start early
779
        // WARNING: line_start, line_number and line_ena change at once
780
    end
781
end
782
 
783
endmodule
784
 
785
/*! \brief Video output generator from bitplain and sprite video data input.
786
 */
787
module video_priority(
788
    input CLK_I,
789
    input reset_n,
790
 
791
    input line_start,
792
    input line_pre_start,
793
    input [8:0] line_number,
794
    input [8:0] column_number,
795
    output window_line_enable,
796
 
797
    input write_ena,
798
    // 0:   COLOR00,    COLOR01,
799
    // 1:   COLOR02,    COLOR03,
800
    // 2:   COLOR04,    COLOR05,
801
    // 3:   COLOR06,    COLOR07,
802
    // 4:   COLOR08,    COLOR09,
803
    // 5:   COLOR10,    COLOR11,
804
    // 6:   COLOR12,    COLOR13,
805
    // 7:   COLOR14,    COLOR15,
806
    // 8:   COLOR16,    COLOR17,
807
    // 9:   COLOR18,    COLOR19,
808
    // 10:  COLOR20,    COLOR21,
809
    // 11:  COLOR22,    COLOR23,
810
    // 12:  COLOR24,    COLOR25,
811
    // 13:  COLOR26,    COLOR27,
812
    // 14:  COLOR28,    COLOR29,
813
    // 15:  COLOR30,    COLOR31,
814
    // 16:      DIWSTRT [15:0],     COPINS      [31:16], * COPINS not implemented  
815
    // 17:      DIWSTOP [31:16],    DDFSTART    [15:0], *
816
    // 18:      CLXCON  [31:16],    INTENA      [15:0], *
817
    // 19:      BPLCON2 [31:16],    NOT USED    [15:0],
818
    // read:    CLXDAT  [15:0],     JOY1DAT     [31:16] *
819
    input [4:0] write_address,
820
    input [31:0] write_data,
821
    input [3:0] write_sel,
822
 
823
    input [5:0] bpl_color,
824
    input [1:0] sprite0_color,
825
    input [1:0] sprite1_color,
826
    input sprite01_attached,
827
    input [1:0] sprite2_color,
828
    input [1:0] sprite3_color,
829
    input sprite23_attached,
830
    input [1:0] sprite4_color,
831
    input [1:0] sprite5_color,
832
    input sprite45_attached,
833
    input [1:0] sprite6_color,
834
    input [1:0] sprite7_color,
835
    input sprite67_attached,
836
 
837
    input clx_dat_read,
838
    output reg [15:0] clx_dat,
839
 
840
    input [10:0] bpl_con0,
841
 
842
    // video interface
843
    output reg burst_write_request,
844
    output reg [31:2] burst_write_address,
845
    output [35:0] burst_write_data,
846
    input burst_write_ready
847
);
848
 
849
// lowres, noninterlaced
850
reg [15:0] diw_start;
851
wire [8:0] hstart;
852
wire [8:0] vstart;
853
assign hstart = { 1'b0, diw_start[7:0] };
854
assign vstart = { 1'b0, diw_start[15:8]};
855
 
856
// lowres, noninterlaced
857
reg [15:0] diw_stop;
858
wire [8:0] hstop;
859
wire [8:0] vstop;
860
assign hstop = { 1'b1, diw_stop[7:0] };
861
assign vstop = { ~diw_stop[15], diw_stop[15:8] };
862
 
863
assign window_line_enable = (line_number >= vstart && line_number < vstop);
864
wire screen_line_enable;
865
assign screen_line_enable = (line_number >= 9'h2C && line_number < 9'h12C);
866
 
867
// output reg [15:0] clx_dat;
868
reg [15:0] clx_con;
869
 
870
reg [6:0] bpl_con2;
871
 
872
reg [11:0] color00;
873
reg [11:0] color01;
874
reg [11:0] color02;
875
reg [11:0] color03;
876
reg [11:0] color04;
877
reg [11:0] color05;
878
reg [11:0] color06;
879
reg [11:0] color07;
880
reg [11:0] color08;
881
reg [11:0] color09;
882
reg [11:0] color10;
883
reg [11:0] color11;
884
reg [11:0] color12;
885
reg [11:0] color13;
886
reg [11:0] color14;
887
reg [11:0] color15;
888
reg [11:0] color16;
889
reg [11:0] color17;
890
reg [11:0] color18;
891
reg [11:0] color19;
892
reg [11:0] color20;
893
reg [11:0] color21;
894
reg [11:0] color22;
895
reg [11:0] color23;
896
reg [11:0] color24;
897
reg [11:0] color25;
898
reg [11:0] color26;
899
reg [11:0] color27;
900
reg [11:0] color28;
901
reg [11:0] color29;
902
reg [11:0] color30;
903
reg [11:0] color31;
904
 
905
reg [7:0] line_ram_addr;
906
reg [35:0] line_ram_data;
907
altsyncram line_ram_inst(
908
        .clock0(CLK_I),
909
 
910
        .address_a(line_ram_addr),
911
        .wren_a(screen_line_enable == 1'b1 && column_number >= 9'h81 &&
912
            ((column_number == 9'h1C1 && line_ram_counter == 3'd1) || (column_number < 9'h1C1 && line_ram_counter == 3'd3))),
913
        .data_a(
914
        (column_number == 9'h1C1 && line_ram_counter == 3'd1)? { final_color_value, 24'd0 } : { line_ram_data[23:0], final_color_value }
915
    ),
916
        .q_a(burst_write_data)
917
);
918
defparam
919
    line_ram_inst.operation_mode = "SINGLE_PORT",
920
    line_ram_inst.width_a = 36,
921
    line_ram_inst.widthad_a = 8;
922
 
923
// Collision detection
924
// - sprite group - sprite group(1); sprite group - any playfield(2); playfield - playfield(3)
925
// - clxdat: does not depend on dual-playfield mode
926
// - clxcon: all disabled bitplains = collision always detected
927
wire clx_sprite_group_01;
928
assign clx_sprite_group_01 = (sprite0_color != 2'b00 || (clx_con[12] == 1'b1 && sprite1_color != 2'b00));
929
wire clx_sprite_group_23;
930
assign clx_sprite_group_23 = (sprite2_color != 2'b00 || (clx_con[13] == 1'b1 && sprite3_color != 2'b00));
931
wire clx_sprite_group_45;
932
assign clx_sprite_group_45 = (sprite4_color != 2'b00 || (clx_con[14] == 1'b1 && sprite5_color != 2'b00));
933
wire clx_sprite_group_67;
934
assign clx_sprite_group_67 = (sprite6_color != 2'b00 || (clx_con[15] == 1'b1 && sprite7_color != 2'b00));
935
 
936
wire clx_even_bpls;
937
assign clx_even_bpls =  (clx_con[7] == 1'b1 && clx_con[1] == bpl_color[1]) ||  (clx_con[9] == 1'b1 && clx_con[3] == bpl_color[3]) ||
938
                        (clx_con[11] == 1'b1 && clx_con[5] == bpl_color[5]);
939
wire clx_odd_bpls;
940
assign clx_odd_bpls =   (clx_con[6] == 1'b1 && clx_con[0] == bpl_color[0]) || (clx_con[8] == 1'b1 && clx_con[2] == bpl_color[2]) ||
941
                        (clx_con[10] == 1'b1 && clx_con[4] == bpl_color[4]);
942
 
943
wire [14:0] clx_detected;
944
assign clx_detected = {
945
    clx_sprite_group_45 && clx_sprite_group_67,
946
    clx_sprite_group_23 && clx_sprite_group_67,
947
    clx_sprite_group_23  && clx_sprite_group_45,
948
    clx_sprite_group_01 && clx_sprite_group_67,
949
    clx_sprite_group_01  && clx_sprite_group_45,
950
    clx_sprite_group_01  && clx_sprite_group_23,
951
    (clx_con[11:6] == 6'd0) || (clx_even_bpls == 1'b1 && clx_sprite_group_67),
952
    (clx_con[11:6] == 6'd0) || (clx_even_bpls == 1'b1 && clx_sprite_group_45),
953
    (clx_con[11:6] == 6'd0) || (clx_even_bpls == 1'b1 && clx_sprite_group_23),
954
    (clx_con[11:6] == 6'd0) || (clx_even_bpls == 1'b1 && clx_sprite_group_01),
955
    (clx_con[11:6] == 6'd0) || (clx_odd_bpls == 1'b1 && clx_sprite_group_67),
956
    (clx_con[11:6] == 6'd0) || (clx_odd_bpls == 1'b1 && clx_sprite_group_45),
957
    (clx_con[11:6] == 6'd0) || (clx_odd_bpls == 1'b1 && clx_sprite_group_23),
958
    (clx_con[11:6] == 6'd0) || (clx_odd_bpls == 1'b1 && clx_sprite_group_01),
959
    (clx_con[11:6] == 6'd0) || (clx_odd_bpls == 1'b1 && clx_even_bpls == 1'b1)
960
};
961
 
962
// Video priority
963
// - sprite 0 more important than 1,2,3,4,5,6,7
964
// - for priority and collision, sprite groups: 0-1, 2-3, 4-5, 6-7
965
// - PF2PRI = 0, PF1 more important than PF2; PF2PRI = 1, PL2 more important than PL1
966
// - PF2P2 - PF2P0 for non-dual playfield or PF2
967
// - PF1P2 - PF1P0 for PF1
968
//      - PF(0) SP01 PF(1) SP23 PF(2) SP45 PF(3) SP67 PF(4)
969
//
970
// Dual-playfield: bpl_con0[5] == 1'b1; PF1 color lookup 0(transparent)-7; PF2 color lookup 8(transparent)-15
971
// Attached sprites: 0-1, 2-3, 4-5, 6-7; color 16(transparent)-31; { sprite1_color[1:0], sprite0_color[1:0] }
972
wire [4:0] spr0_color;
973
assign spr0_color = { 1'b1, (sprite01_attached == 1'b1)? sprite1_color[1:0] : 2'b00, sprite0_color[1:0] };
974
wire [4:0] spr1_color;
975
assign spr1_color = (sprite01_attached == 1'b1)? spr0_color : { 3'b100, sprite1_color[1:0] };
976
 
977
wire [4:0] spr2_color;
978
assign spr2_color = { 1'b1, (sprite23_attached == 1'b1)? sprite3_color[1:0] : 2'b01, sprite2_color[1:0] };
979
wire [4:0] spr3_color;
980
assign spr3_color = (sprite23_attached == 1'b1)? spr2_color : { 3'b101, sprite3_color[1:0] };
981
 
982
wire [4:0] spr4_color;
983
assign spr4_color = { 1'b1, (sprite45_attached == 1'b1)? sprite5_color[1:0] : 2'b10, sprite4_color[1:0] };
984
wire [4:0] spr5_color;
985
assign spr5_color = (sprite45_attached == 1'b1)? spr4_color : { 3'b110, sprite5_color[1:0] };
986
 
987
wire [4:0] spr6_color;
988
assign spr6_color = { 1'b1, (sprite67_attached == 1'b1)? sprite7_color[1:0] : 2'b11, sprite6_color[1:0] };
989
wire [4:0] spr7_color;
990
assign spr7_color = (sprite67_attached == 1'b1)? spr6_color : { 3'b111, sprite7_color[1:0] };
991
 
992
wire sprite01_exists;
993
assign sprite01_exists = (sprite0_color[1:0] != 2'b00 || sprite1_color[1:0] != 2'b00);
994
wire sprite23_exists;
995
assign sprite23_exists = (sprite2_color[1:0] != 2'b00 || sprite3_color[1:0] != 2'b00);
996
wire sprite45_exists;
997
assign sprite45_exists = (sprite4_color[1:0] != 2'b00 || sprite5_color[1:0] != 2'b00);
998
wire sprite67_exists;
999
assign sprite67_exists = (sprite6_color[1:0] != 2'b00 || sprite7_color[1:0] != 2'b00);
1000
 
1001
wire [4:0] pf1_color;
1002
assign pf1_color = { 2'b0, bpl_color[4], bpl_color[2], bpl_color[0] };
1003
 
1004
// Dual playfield: bpl_con0[5] == 1'b1
1005
wire [4:0] pf2_color;
1006
assign pf2_color = (bpl_con0[5] == 1'b1) ? { 2'b1, bpl_color[5], bpl_color[3], bpl_color[1] } : bpl_color[4:0];
1007
 
1008
// bpl_con2[6] PF2PRI
1009
wire pf1_exists;
1010
assign pf1_exists = (bpl_con0[5] == 1'b1) ?
1011
    ((bpl_con2[6] == 1'b0) ? (pf1_color[2:0] != 3'd0) : ((pf2_color[2:0] != 3'd0) ? 1'b0 : (pf1_color[2:0] != 3'd0))) :
1012
    1'b0;
1013
 
1014
wire pf2_exists;
1015
assign pf2_exists = (bpl_con0[5] == 1'b1) ?
1016
    ((bpl_con2[6] == 1'b1) ? (pf2_color[2:0] != 3'd0) : ((pf1_color[2:0] != 3'd0) ? 1'b0 : (pf2_color[2:0] != 3'd0))) :
1017
    (pf2_color[4:0] != 5'd0);
1018
 
1019
wire [4:0] final_color;
1020
assign final_color =
1021
    (pf1_exists == 1'b1 && bpl_con2[2:0] == 3'd0) ? pf1_color :
1022
    (pf2_exists == 1'b1 && bpl_con2[5:3] == 3'd0) ? pf2_color :
1023
    (sprite01_exists) ? ((sprite0_color[1:0] != 2'b00) ? spr0_color : spr1_color) :
1024
    (pf1_exists == 1'b1 && bpl_con2[2:0] == 3'd1) ? pf1_color :
1025
    (pf2_exists == 1'b1 && bpl_con2[5:3] == 3'd1) ? pf2_color :
1026
    (sprite23_exists) ? ((sprite2_color[1:0] != 2'b00) ? spr2_color : spr3_color) :
1027
    (pf1_exists == 1'b1 && bpl_con2[2:0] == 3'd2) ? pf1_color :
1028
    (pf2_exists == 1'b1 && bpl_con2[5:3] == 3'd2) ? pf2_color :
1029
    (sprite45_exists) ? ((sprite4_color[1:0] != 2'b00) ? spr4_color : spr5_color) :
1030
    (pf1_exists == 1'b1 && bpl_con2[2:0] == 3'd3) ? pf1_color :
1031
    (pf2_exists == 1'b1 && bpl_con2[5:3] == 3'd3) ? pf2_color :
1032
    (sprite67_exists) ? ((sprite6_color[1:0] != 2'b00) ? spr6_color : spr7_color) :
1033
    (pf1_exists == 1'b1 && bpl_con2[2:0] == 3'd4) ? pf1_color :
1034
    (pf2_exists == 1'b1 && bpl_con2[5:3] == 3'd4) ? pf2_color :
1035
    4'd0;
1036
 
1037
// HAM mode
1038
// - Hold and Modify mode, 4096 colors on screen at once, 6-bit pixel: 2-bit control + 4-bit data:
1039
//            - set[6'b00DDDD bpl654321](data - regular color lookup 0-15)
1040
//            - modify-red 6'b01DDDDDD, modify-green 6'b10DDDDDD, modify-blue 6'b11DDDDDD (data - modify that component, leave rest unchanged)
1041
// EHB mode 
1042
wire ham_enabled;
1043
assign ham_enabled = (bpl_con0[6] == 1'b1 && bpl_con0[5] == 1'b0 && bpl_con0[10] == 1'b0 && (bpl_con0[9:7] == 3'd6 || bpl_con0[9:7] == 3'd5));
1044
wire ehb_enabled;
1045
assign ehb_enabled = (bpl_con0[6] == 1'b0 && bpl_con0[5] == 1'b0 && bpl_con0[10] == 1'b0 && bpl_con0[9:7] == 3'd6);
1046
 
1047
wire [11:0] color_value_before_ehb;
1048
assign color_value_before_ehb =
1049
    (ham_enabled == 1'b1 && bpl_color[5:4] == 2'b01) ? { bpl_color[3:0], last_color_value[7:0] } :
1050
    (ham_enabled == 1'b1 && bpl_color[5:4] == 2'b10) ? { last_color_value[11:8], bpl_color[3:0], last_color_value[3:0] } :
1051
    (ham_enabled == 1'b1 && bpl_color[5:4] == 2'b11) ? { last_color_value[11:4], bpl_color[3:0] } :
1052
    (final_color == 5'd0) ? color00 :
1053
    (final_color == 5'd1) ? color01 :
1054
    (final_color == 5'd2) ? color02 :
1055
    (final_color == 5'd3) ? color03 :
1056
    (final_color == 5'd4) ? color04 :
1057
    (final_color == 5'd5) ? color05 :
1058
    (final_color == 5'd6) ? color06 :
1059
    (final_color == 5'd7) ? color07 :
1060
    (final_color == 5'd8) ? color08 :
1061
    (final_color == 5'd9) ? color09 :
1062
    (final_color == 5'd10) ? color10 :
1063
    (final_color == 5'd11) ? color11 :
1064
    (final_color == 5'd12) ? color12 :
1065
    (final_color == 5'd13) ? color13 :
1066
    (final_color == 5'd14) ? color14 :
1067
    (final_color == 5'd15) ? color15 :
1068
    (final_color == 5'd16) ? color16 :
1069
    (final_color == 5'd17) ? color17 :
1070
    (final_color == 5'd18) ? color18 :
1071
    (final_color == 5'd19) ? color19 :
1072
    (final_color == 5'd20) ? color20 :
1073
    (final_color == 5'd21) ? color21 :
1074
    (final_color == 5'd22) ? color22 :
1075
    (final_color == 5'd23) ? color23 :
1076
    (final_color == 5'd24) ? color24 :
1077
    (final_color == 5'd25) ? color25 :
1078
    (final_color == 5'd26) ? color26 :
1079
    (final_color == 5'd27) ? color27 :
1080
    (final_color == 5'd28) ? color28 :
1081
    (final_color == 5'd29) ? color29 :
1082
    (final_color == 5'd30) ? color30 :
1083
    color31;
1084
 
1085
wire [11:0] final_color_value;
1086
assign final_color_value =
1087
    (column_number < hstart || column_number > hstop) ? color00 :
1088
    (ehb_enabled == 1'b1) ? { 1'b0,color_value_before_ehb[11:9], 1'b0,color_value_before_ehb[7:5], 1'b0,color_value_before_ehb[3:1] } :
1089
    color_value_before_ehb;
1090
 
1091
reg [11:0] last_color_value;
1092
reg [2:0] line_ram_counter;
1093
always @(posedge CLK_I or negedge reset_n) begin
1094
    if(reset_n == 1'b0) begin
1095
        clx_dat <= 16'd0;
1096
        burst_write_request <= 1'b0;
1097
        burst_write_address <= 30'd0;
1098
        diw_start <= 16'h2C81;
1099
        diw_stop <= 16'h2CC1;
1100
        clx_con <= 16'd0;
1101
        bpl_con2 <= 7'd0;
1102
        color00 <= 12'd0;
1103
        color01 <= 12'd0;
1104
        color02 <= 12'd0;
1105
        color03 <= 12'd0;
1106
        color04 <= 12'd0;
1107
        color05 <= 12'd0;
1108
        color06 <= 12'd0;
1109
        color07 <= 12'd0;
1110
        color08 <= 12'd0;
1111
        color09 <= 12'd0;
1112
        color10 <= 12'd0;
1113
        color11 <= 12'd0;
1114
        color12 <= 12'd0;
1115
        color13 <= 12'd0;
1116
        color14 <= 12'd0;
1117
        color15 <= 12'd0;
1118
        color16 <= 12'd0;
1119
        color17 <= 12'd0;
1120
        color18 <= 12'd0;
1121
        color19 <= 12'd0;
1122
        color20 <= 12'd0;
1123
        color21 <= 12'd0;
1124
        color22 <= 12'd0;
1125
        color23 <= 12'd0;
1126
        color24 <= 12'd0;
1127
        color25 <= 12'd0;
1128
        color26 <= 12'd0;
1129
        color27 <= 12'd0;
1130
        color28 <= 12'd0;
1131
        color29 <= 12'd0;
1132
        color30 <= 12'd0;
1133
        color31 <= 12'd0;
1134
        line_ram_addr <= 8'd0;
1135
        line_ram_data <= 36'd0;
1136
        last_color_value <= 12'd0;
1137
        line_ram_counter <= 3'd0;
1138
    end
1139
    else begin
1140
 
1141
        if(screen_line_enable == 1'b1 && column_number >= 9'h81 && column_number == 9'h1C1 && line_ram_counter == 3'd1) begin
1142
            line_ram_addr <= 8'd0;
1143
            line_ram_counter <= 3'd4;
1144
            last_color_value <= final_color_value;
1145
        end
1146
        else if(screen_line_enable == 1'b1 && column_number >= 9'h81 && column_number < 9'h1C1 && line_ram_counter == 3'd3) begin
1147
            line_ram_addr <= line_ram_addr + 8'd1;
1148
            line_ram_counter <= 3'd1;
1149
            last_color_value <= final_color_value;
1150
        end
1151
        else if(screen_line_enable == 1'b1 && column_number >= 9'h81 && column_number < 9'h1C1 && line_ram_counter == 3'd0) begin
1152
            line_ram_counter <= line_ram_counter + 3'd1;
1153
        end
1154
        else if(screen_line_enable == 1'b1 && column_number >= 9'h81 && column_number < 9'h1C1 && line_ram_counter < 3'd4) begin
1155
            line_ram_counter <= line_ram_counter + 3'd1;
1156
            line_ram_data <= { line_ram_data[23:0], final_color_value };
1157
            last_color_value <= final_color_value;
1158
        end
1159
        else if(line_ram_counter == 3'd4) begin
1160
            if(burst_write_ready == 1'b1 && line_ram_addr <= 8'd213) begin
1161
                line_ram_addr <= line_ram_addr + 8'd1;
1162
            end
1163
            else if(burst_write_ready == 1'b1 && line_ram_addr == 8'd214) begin
1164
                line_ram_counter <= 3'd0;
1165
            end
1166
        end
1167
        else begin
1168
            line_ram_addr <= 8'd0;
1169
            last_color_value <= color00;
1170
            line_ram_counter <= 3'd0;
1171
        end
1172
 
1173
        if(screen_line_enable == 1'b1 && column_number >= 9'h81 && column_number == 9'h1C1 && line_ram_counter == 3'd1) begin
1174
            burst_write_request <= 1'b1;
1175
        end
1176
        else if(line_ram_counter == 3'd4 && line_ram_addr == 8'd214) begin
1177
            burst_write_request <= 1'b0;
1178
            burst_write_address <= burst_write_address + 30'd216; // 640/3 = 213.(3) = 214 + 2 for %4 =0
1179
        end
1180
        else if(screen_line_enable == 1'b0) begin
1181
            burst_write_address <= `VIDEO_BUFFER_DIV_4; // start of video buffer
1182
        end
1183
 
1184
        if(clx_dat_read == 1'b1) clx_dat <= 16'd0;
1185
        else clx_dat <= clx_dat | { 1'b0, clx_detected };
1186
 
1187
        if(write_ena == 1'b1) begin
1188
            if(write_address == 5'd0 && write_sel[0] == 1'b1) color01[7:0] <= write_data[7:0];
1189
            if(write_address == 5'd0 && write_sel[1] == 1'b1) color01[11:8] <= write_data[11:8];
1190
            if(write_address == 5'd0 && write_sel[2] == 1'b1) color00[7:0] <= write_data[23:16];
1191
            if(write_address == 5'd0 && write_sel[3] == 1'b1) color00[11:8] <= write_data[27:24];
1192
            if(write_address == 5'd1 && write_sel[0] == 1'b1) color03[7:0] <= write_data[7:0];
1193
            if(write_address == 5'd1 && write_sel[1] == 1'b1) color03[11:8] <= write_data[11:8];
1194
            if(write_address == 5'd1 && write_sel[2] == 1'b1) color02[7:0] <= write_data[23:16];
1195
            if(write_address == 5'd1 && write_sel[3] == 1'b1) color02[11:8] <= write_data[27:24];
1196
            if(write_address == 5'd2 && write_sel[0] == 1'b1) color05[7:0] <= write_data[7:0];
1197
            if(write_address == 5'd2 && write_sel[1] == 1'b1) color05[11:8] <= write_data[11:8];
1198
            if(write_address == 5'd2 && write_sel[2] == 1'b1) color04[7:0] <= write_data[23:16];
1199
            if(write_address == 5'd2 && write_sel[3] == 1'b1) color04[11:8] <= write_data[27:24];
1200
            if(write_address == 5'd3 && write_sel[0] == 1'b1) color07[7:0] <= write_data[7:0];
1201
            if(write_address == 5'd3 && write_sel[1] == 1'b1) color07[11:8] <= write_data[11:8];
1202
            if(write_address == 5'd3 && write_sel[2] == 1'b1) color06[7:0] <= write_data[23:16];
1203
            if(write_address == 5'd3 && write_sel[3] == 1'b1) color06[11:8] <= write_data[27:24];
1204
            if(write_address == 5'd4 && write_sel[0] == 1'b1) color09[7:0] <= write_data[7:0];
1205
            if(write_address == 5'd4 && write_sel[1] == 1'b1) color09[11:8] <= write_data[11:8];
1206
            if(write_address == 5'd4 && write_sel[2] == 1'b1) color08[7:0] <= write_data[23:16];
1207
            if(write_address == 5'd4 && write_sel[3] == 1'b1) color08[11:8] <= write_data[27:24];
1208
            if(write_address == 5'd5 && write_sel[0] == 1'b1) color11[7:0] <= write_data[7:0];
1209
            if(write_address == 5'd5 && write_sel[1] == 1'b1) color11[11:8] <= write_data[11:8];
1210
            if(write_address == 5'd5 && write_sel[2] == 1'b1) color10[7:0] <= write_data[23:16];
1211
            if(write_address == 5'd5 && write_sel[3] == 1'b1) color10[11:8] <= write_data[27:24];
1212
            if(write_address == 5'd6 && write_sel[0] == 1'b1) color13[7:0] <= write_data[7:0];
1213
            if(write_address == 5'd6 && write_sel[1] == 1'b1) color13[11:8] <= write_data[11:8];
1214
            if(write_address == 5'd6 && write_sel[2] == 1'b1) color12[7:0] <= write_data[23:16];
1215
            if(write_address == 5'd6 && write_sel[3] == 1'b1) color12[11:8] <= write_data[27:24];
1216
            if(write_address == 5'd7 && write_sel[0] == 1'b1) color15[7:0] <= write_data[7:0];
1217
            if(write_address == 5'd7 && write_sel[1] == 1'b1) color15[11:8] <= write_data[11:8];
1218
            if(write_address == 5'd7 && write_sel[2] == 1'b1) color14[7:0] <= write_data[23:16];
1219
            if(write_address == 5'd7 && write_sel[3] == 1'b1) color14[11:8] <= write_data[27:24];
1220
            if(write_address == 5'd8 && write_sel[0] == 1'b1) color17[7:0] <= write_data[7:0];
1221
            if(write_address == 5'd8 && write_sel[1] == 1'b1) color17[11:8] <= write_data[11:8];
1222
            if(write_address == 5'd8 && write_sel[2] == 1'b1) color16[7:0] <= write_data[23:16];
1223
            if(write_address == 5'd8 && write_sel[3] == 1'b1) color16[11:8] <= write_data[27:24];
1224
            if(write_address == 5'd9 && write_sel[0] == 1'b1) color19[7:0] <= write_data[7:0];
1225
            if(write_address == 5'd9 && write_sel[1] == 1'b1) color19[11:8] <= write_data[11:8];
1226
            if(write_address == 5'd9 && write_sel[2] == 1'b1) color18[7:0] <= write_data[23:16];
1227
            if(write_address == 5'd9 && write_sel[3] == 1'b1) color18[11:8] <= write_data[27:24];
1228
            if(write_address == 5'd10 && write_sel[0] == 1'b1) color21[7:0] <= write_data[7:0];
1229
            if(write_address == 5'd10 && write_sel[1] == 1'b1) color21[11:8] <= write_data[11:8];
1230
            if(write_address == 5'd10 && write_sel[2] == 1'b1) color20[7:0] <= write_data[23:16];
1231
            if(write_address == 5'd10 && write_sel[3] == 1'b1) color20[11:8] <= write_data[27:24];
1232
            if(write_address == 5'd11 && write_sel[0] == 1'b1) color23[7:0] <= write_data[7:0];
1233
            if(write_address == 5'd11 && write_sel[1] == 1'b1) color23[11:8] <= write_data[11:8];
1234
            if(write_address == 5'd11 && write_sel[2] == 1'b1) color22[7:0] <= write_data[23:16];
1235
            if(write_address == 5'd11 && write_sel[3] == 1'b1) color22[11:8] <= write_data[27:24];
1236
            if(write_address == 5'd12 && write_sel[0] == 1'b1) color25[7:0] <= write_data[7:0];
1237
            if(write_address == 5'd12 && write_sel[1] == 1'b1) color25[11:8] <= write_data[11:8];
1238
            if(write_address == 5'd12 && write_sel[2] == 1'b1) color24[7:0] <= write_data[23:16];
1239
            if(write_address == 5'd12 && write_sel[3] == 1'b1) color24[11:8] <= write_data[27:24];
1240
            if(write_address == 5'd13 && write_sel[0] == 1'b1) color27[7:0] <= write_data[7:0];
1241
            if(write_address == 5'd13 && write_sel[1] == 1'b1) color27[11:8] <= write_data[11:8];
1242
            if(write_address == 5'd13 && write_sel[2] == 1'b1) color26[7:0] <= write_data[23:16];
1243
            if(write_address == 5'd13 && write_sel[3] == 1'b1) color26[11:8] <= write_data[27:24];
1244
            if(write_address == 5'd14 && write_sel[0] == 1'b1) color29[7:0] <= write_data[7:0];
1245
            if(write_address == 5'd14 && write_sel[1] == 1'b1) color29[11:8] <= write_data[11:8];
1246
            if(write_address == 5'd14 && write_sel[2] == 1'b1) color28[7:0] <= write_data[23:16];
1247
            if(write_address == 5'd14 && write_sel[3] == 1'b1) color28[11:8] <= write_data[27:24];
1248
            if(write_address == 5'd15 && write_sel[0] == 1'b1) color31[7:0] <= write_data[7:0];
1249
            if(write_address == 5'd15 && write_sel[1] == 1'b1) color31[11:8] <= write_data[11:8];
1250
            if(write_address == 5'd15 && write_sel[2] == 1'b1) color30[7:0] <= write_data[23:16];
1251
            if(write_address == 5'd15 && write_sel[3] == 1'b1) color30[11:8] <= write_data[27:24];
1252
            // 16:      DIWSTRT [15:0],     COPINS      [31:16], * COPINS not implemented  
1253
            // 17:      DIWSTOP [31:16],    DDFSTART    [15:0], *
1254
            // 18:      CLXCON  [31:16],    INTENA      [15:0], *
1255
            // 19:      BPLCON2 [31:16],    NOT USED    [15:0],
1256
            if(write_address == 5'd16 && write_sel[0] == 1'b1) diw_start[7:0] <= write_data[7:0];
1257
            if(write_address == 5'd16 && write_sel[1] == 1'b1) diw_start[15:8] <= write_data[15:8];
1258
            if(write_address == 5'd16 && write_sel[2] == 1'b1) ;
1259
            if(write_address == 5'd16 && write_sel[3] == 1'b1) ;
1260
            if(write_address == 5'd17 && write_sel[0] == 1'b1) ;
1261
            if(write_address == 5'd17 && write_sel[1] == 1'b1) ;
1262
            if(write_address == 5'd17 && write_sel[2] == 1'b1) diw_stop[7:0] <= write_data[23:16];
1263
            if(write_address == 5'd17 && write_sel[3] == 1'b1) diw_stop[15:8] <= write_data[31:24];
1264
            if(write_address == 5'd18 && write_sel[0] == 1'b1) ;
1265
            if(write_address == 5'd18 && write_sel[1] == 1'b1) ;
1266
            if(write_address == 5'd18 && write_sel[2] == 1'b1) clx_con[7:0] <= write_data[23:16];
1267
            if(write_address == 5'd18 && write_sel[3] == 1'b1) clx_con[15:8] <= write_data[31:24];
1268
            if(write_address == 5'd19 && write_sel[0] == 1'b1) ;
1269
            if(write_address == 5'd19 && write_sel[1] == 1'b1) ;
1270
            if(write_address == 5'd19 && write_sel[2] == 1'b1) bpl_con2 <= write_data[22:16];
1271
            if(write_address == 5'd19 && write_sel[3] == 1'b1) ;
1272
        end
1273
    end
1274
end
1275
 
1276
endmodule
1277
 
1278
/*! \brief Bitplain top level module with multiplexers to internal bitplain module instances.
1279
 */
1280
module bitplains(
1281
    input CLK_I,
1282
    input reset_n,
1283
 
1284
    input line_start,
1285
    input [8:0] column_number,
1286
 
1287
    // video interface - read
1288
    input burst_read_enabled,
1289
        output burst_read_request,
1290
        output [31:2] burst_read_address,
1291
        input burst_read_ready,
1292
        input [31:0] burst_read_data,
1293
 
1294
    input write_ena,
1295
    // 0:   BPL1PTH,    BPL1PTL,
1296
    // 1:   BPL2PTH,    BPL2PTL,
1297
    // 2:   BPL3PTH,    BPL3PTL,
1298
    // 3:   BPL4PTH,    BPL4PTL,
1299
    // 4:   BPL5PTH,    BPL5PTL,
1300
    // 5:   BPL6PTH,    BPL6PTL,
1301
    // 6:       DDFSTRT [15:0],     DIWSTOP [31:16], *
1302
    // 7:       DDFSTOP [31:16],    DMACON  [15:0], *
1303
    // 8:   BPLCON0,    BPLCON1,
1304
    // 9:   BPL1MOD,    BPL2MOD,
1305
    // 10:  BPL1DAT,    BPL2DAT,
1306
    // 11:  BPL3DAT,    BPL4DAT,
1307
    // 12:  BPL5DAT,    BPL6DAT
1308
    input [3:0] write_address,
1309
    input [31:0] write_data,
1310
    input [3:0] write_sel,
1311
 
1312
    output [7:0] disable_sprites,
1313
    output reg [10:0] bpl_con0,
1314
    output [5:0] color,
1315
 
1316
    input [8:0] line_number
1317
);
1318
 
1319
assign disable_sprites = {
1320
    (ddf_start[8:3] < 6'd14),
1321
    (ddf_start[8:3] < 6'd13),
1322
    (ddf_start[8:3] < 6'd12),
1323
    (ddf_start[8:3] < 6'd11),
1324
    (ddf_start[8:3] < 6'd10),
1325
    (ddf_start[8:3] < 6'd9),
1326
    (ddf_start[8:3] < 6'd8),
1327
    (ddf_start[8:3] < 6'd7)
1328
};
1329
 
1330
reg [8:3] ddf_start;
1331
reg [8:3] ddf_stop;
1332
 
1333
reg [31:0] bpl_modulo;
1334
 
1335
// output reg [10:0] bpl_con0
1336
reg [7:0] bpl_con1;
1337
 
1338
reg [5:0] dma_reqs_reg;
1339
wire [5:0] dma_reqs;
1340
wire [2:0] selected_bpl;
1341
assign selected_bpl =
1342
    (dma_reqs_reg[0] == 1'b1) ? 3'd1 :
1343
    (dma_reqs_reg[1] == 1'b1) ? 3'd2 :
1344
    (dma_reqs_reg[2] == 1'b1) ? 3'd3 :
1345
    (dma_reqs_reg[3] == 1'b1) ? 3'd4 :
1346
    (dma_reqs_reg[4] == 1'b1) ? 3'd5 :
1347
    (dma_reqs_reg[5] == 1'b1) ? 3'd6 :
1348
    3'd0;
1349
 
1350
assign burst_read_address =
1351
    (selected_bpl == 3'd1) ? dma_address_1 :
1352
    (selected_bpl == 3'd2) ? dma_address_2 :
1353
    (selected_bpl == 3'd3) ? dma_address_3 :
1354
    (selected_bpl == 3'd4) ? dma_address_4 :
1355
    (selected_bpl == 3'd5) ? dma_address_5 :
1356
    (selected_bpl == 3'd6) ? dma_address_6 :
1357
    30'd0;
1358
 
1359
assign burst_read_request =
1360
    (selected_bpl == 3'd1) ? dma_reqs[0] :
1361
    (selected_bpl == 3'd2) ? dma_reqs[1] :
1362
    (selected_bpl == 3'd3) ? dma_reqs[2] :
1363
    (selected_bpl == 3'd4) ? dma_reqs[3] :
1364
    (selected_bpl == 3'd5) ? dma_reqs[4] :
1365
    (selected_bpl == 3'd6) ? dma_reqs[5] :
1366
    1'b0;
1367
 
1368
wire [31:2] dma_address_1;
1369
bitplain bitplain_1(
1370
    .CLK_I(CLK_I),
1371
    .reset_n(reset_n),
1372
 
1373
    .line_start(line_start),
1374
    .column_number(column_number),
1375
 
1376
    .burst_read_enabled(burst_read_enabled == 1'b1 && bpl_con0[9:7] >= 3'd1),
1377
    .burst_read_request(dma_reqs[0]),
1378
    .burst_read_address(dma_address_1),
1379
    .burst_read_ready(burst_read_ready == 1'b1 && selected_bpl == 3'd1),
1380
    .burst_read_data(burst_read_data),
1381
 
1382
    .write_ena(write_ena == 1'b1 && (write_address == 4'd0 || write_address == 4'd10)),
1383
    // 0:   BPLxPTH,    BPLxPTL,
1384
    // 1:   BPLxDAT,    16'd0
1385
    .write_address( (write_address == 4'd0)? 1'b0       : 1'b1),
1386
    .write_data(    (write_address == 4'd0)? write_data : {write_data[31:16], 16'd0}),
1387
    .write_sel(     (write_address == 4'd0)? write_sel  : {write_sel[3:2], 2'b0}),
1388
 
1389
    .bpl_con0(bpl_con0),
1390
    .bpl_delay(bpl_con1[3:0]),
1391
    .bpl_modulo(bpl_modulo[31:16]),
1392
    .ddf_start(ddf_start),
1393
    .ddf_stop(ddf_stop),
1394
 
1395
    .color(color[0]),
1396
 
1397
    .line_number(line_number)
1398
);
1399
wire [31:2] dma_address_2;
1400
bitplain bitplain_2(
1401
    .CLK_I(CLK_I),
1402
    .reset_n(reset_n),
1403
 
1404
    .line_start(line_start),
1405
    .column_number(column_number),
1406
 
1407
    .burst_read_enabled(burst_read_enabled == 1'b1 && bpl_con0[9:7] >= 3'd2),
1408
    .burst_read_request(dma_reqs[1]),
1409
    .burst_read_address(dma_address_2),
1410
    .burst_read_ready(burst_read_ready == 1'b1 && selected_bpl == 3'd2),
1411
    .burst_read_data(burst_read_data),
1412
 
1413
    .write_ena(write_ena == 1'b1 && (write_address == 4'd1 || write_address == 4'd10)),
1414
    // 0:   BPLxPTH,    BPLxPTL,
1415
    // 1:   BPLxDAT,    16'd0
1416
    .write_address( (write_address == 4'd1)? 1'b0       : 1'b1),
1417
    .write_data(    (write_address == 4'd1)? write_data : {write_data[15:0], 16'd0}),
1418
    .write_sel(     (write_address == 4'd1)? write_sel  : {write_sel[1:0], 2'b0}),
1419
 
1420
    .bpl_con0(bpl_con0),
1421
    .bpl_delay(bpl_con1[7:4]),
1422
    .bpl_modulo(bpl_modulo[15:0]),
1423
    .ddf_start(ddf_start),
1424
    .ddf_stop(ddf_stop),
1425
 
1426
    .color(color[1]),
1427
 
1428
    .line_number(line_number)
1429
);
1430
wire [31:2] dma_address_3;
1431
bitplain bitplain_3(
1432
    .CLK_I(CLK_I),
1433
    .reset_n(reset_n),
1434
 
1435
    .line_start(line_start),
1436
    .column_number(column_number),
1437
 
1438
    .burst_read_enabled(burst_read_enabled == 1'b1 && bpl_con0[9:7] >= 3'd3),
1439
    .burst_read_request(dma_reqs[2]),
1440
    .burst_read_address(dma_address_3),
1441
    .burst_read_ready(burst_read_ready == 1'b1 && selected_bpl == 3'd3),
1442
    .burst_read_data(burst_read_data),
1443
 
1444
    .write_ena(write_ena == 1'b1 && (write_address == 4'd2 || write_address == 4'd11)),
1445
    // 0:   BPLxPTH,    BPLxPTL,
1446
    // 1:   BPLxDAT,    16'd0
1447
    .write_address( (write_address == 4'd2)? 1'b0       : 1'b1),
1448
    .write_data(    (write_address == 4'd2)? write_data : {write_data[31:16], 16'd0}),
1449
    .write_sel(     (write_address == 4'd2)? write_sel  : {write_sel[3:2], 2'b0}),
1450
 
1451
    .bpl_con0(bpl_con0),
1452
    .bpl_delay(bpl_con1[3:0]),
1453
    .bpl_modulo(bpl_modulo[31:16]),
1454
    .ddf_start(ddf_start),
1455
    .ddf_stop(ddf_stop),
1456
 
1457
    .color(color[2]),
1458
 
1459
    .line_number(line_number)
1460
);
1461
wire [31:2] dma_address_4;
1462
bitplain bitplain_4(
1463
    .CLK_I(CLK_I),
1464
    .reset_n(reset_n),
1465
 
1466
    .line_start(line_start),
1467
    .column_number(column_number),
1468
 
1469
    .burst_read_enabled(burst_read_enabled == 1'b1 && bpl_con0[9:7] >= 3'd4),
1470
    .burst_read_request(dma_reqs[3]),
1471
    .burst_read_address(dma_address_4),
1472
    .burst_read_ready(burst_read_ready == 1'b1 && selected_bpl == 3'd4),
1473
    .burst_read_data(burst_read_data),
1474
 
1475
    .write_ena(write_ena == 1'b1 && (write_address == 4'd3 || write_address == 4'd11)),
1476
    // 0:   BPLxPTH,    BPLxPTL,
1477
    // 1:   BPLxDAT,    16'd0
1478
    .write_address( (write_address == 4'd3)? 1'b0       : 1'b1),
1479
    .write_data(    (write_address == 4'd3)? write_data : {write_data[15:0], 16'd0}),
1480
    .write_sel(     (write_address == 4'd3)? write_sel  : {write_sel[1:0], 2'b0}),
1481
 
1482
    .bpl_con0(bpl_con0),
1483
    .bpl_delay(bpl_con1[7:4]),
1484
    .bpl_modulo(bpl_modulo[15:0]),
1485
    .ddf_start(ddf_start),
1486
    .ddf_stop(ddf_stop),
1487
 
1488
    .color(color[3]),
1489
 
1490
    .line_number(line_number)
1491
);
1492
wire [31:2] dma_address_5;
1493
bitplain bitplain_5(
1494
    .CLK_I(CLK_I),
1495
    .reset_n(reset_n),
1496
 
1497
    .line_start(line_start),
1498
    .column_number(column_number),
1499
 
1500
    .burst_read_enabled(burst_read_enabled == 1'b1 && bpl_con0[9:7] >= 3'd5),
1501
    .burst_read_request(dma_reqs[4]),
1502
    .burst_read_address(dma_address_5),
1503
    .burst_read_ready(burst_read_ready == 1'b1 && selected_bpl == 3'd5),
1504
    .burst_read_data(burst_read_data),
1505
 
1506
    .write_ena(write_ena == 1'b1 && (write_address == 4'd4 || write_address == 4'd12)),
1507
    // 0:   BPLxPTH,    BPLxPTL,
1508
    // 1:   BPLxDAT,    16'd0
1509
    .write_address( (write_address == 4'd4)? 1'b0       : 1'b1),
1510
    .write_data(    (write_address == 4'd4)? write_data : {write_data[31:16], 16'd0}),
1511
    .write_sel(     (write_address == 4'd4)? write_sel  : {write_sel[3:2], 2'b0}),
1512
 
1513
    .bpl_con0(bpl_con0),
1514
    .bpl_delay(bpl_con1[3:0]),
1515
    .bpl_modulo(bpl_modulo[31:16]),
1516
    .ddf_start(ddf_start),
1517
    .ddf_stop(ddf_stop),
1518
 
1519
    .color(color[4]),
1520
 
1521
    .line_number(line_number)
1522
);
1523
wire [31:2] dma_address_6;
1524
bitplain bitplain_6(
1525
    .CLK_I(CLK_I),
1526
    .reset_n(reset_n),
1527
 
1528
    .line_start(line_start),
1529
    .column_number(column_number),
1530
 
1531
    .burst_read_enabled(burst_read_enabled == 1'b1 && bpl_con0[9:7] >= 3'd6),
1532
    .burst_read_request(dma_reqs[5]),
1533
    .burst_read_address(dma_address_6),
1534
    .burst_read_ready(burst_read_ready == 1'b1 && selected_bpl == 3'd6),
1535
    .burst_read_data(burst_read_data),
1536
 
1537
    .write_ena(write_ena == 1'b1 && (write_address == 4'd5 || write_address == 4'd12)),
1538
    // 0:   BPLxPTH,    BPLxPTL,
1539
    // 1:   BPLxDAT,    16'd0
1540
    .write_address( (write_address == 4'd5)? 1'b0       : 1'b1),
1541
    .write_data(    (write_address == 4'd5)? write_data : {write_data[15:0], 16'd0}),
1542
    .write_sel(     (write_address == 4'd5)? write_sel  : {write_sel[1:0], 2'b0}),
1543
 
1544
    .bpl_con0(bpl_con0),
1545
    .bpl_delay(bpl_con1[7:4]),
1546
    .bpl_modulo(bpl_modulo[15:0]),
1547
    .ddf_start(ddf_start),
1548
    .ddf_stop(ddf_stop),
1549
 
1550
    .color(color[5]),
1551
 
1552
    .line_number(line_number)
1553
);
1554
 
1555
always @(posedge CLK_I or negedge reset_n) begin
1556
    if(reset_n == 1'b0) begin
1557
        bpl_con0 <= 11'd0;
1558
        ddf_start <= 6'd0;
1559
        ddf_stop <= 6'd0;
1560
        bpl_modulo <= 32'd0;
1561
        bpl_con1 <= 8'd0;
1562
 
1563
        dma_reqs_reg <= 6'd0;
1564
    end
1565
    else begin
1566
        dma_reqs_reg <= dma_reqs;
1567
 
1568
        // 6:   DDFSTRT [15:0],     DIWSTOP [31:16], *
1569
        // 7:   DDFSTOP [31:16],    DMACON  [15:0], *
1570
        // 8:   BPLCON0,            BPLCON1,
1571
        // 9:   BPL1MOD,            BPL2MOD,
1572
        if(write_ena == 1'b1) begin
1573
            if(write_address == 4'd6 && write_sel[0] == 1'b1) ddf_start <= write_data[7:2];
1574
            if(write_address == 4'd6 && write_sel[1] == 1'b1) ;
1575
            if(write_address == 4'd6 && write_sel[2] == 1'b1) ;
1576
            if(write_address == 4'd6 && write_sel[3] == 1'b1) ;
1577
            if(write_address == 4'd7 && write_sel[0] == 1'b1) ;
1578
            if(write_address == 4'd7 && write_sel[1] == 1'b1) ;
1579
            if(write_address == 4'd7 && write_sel[2] == 1'b1) ddf_stop <= write_data[23:18];
1580
            if(write_address == 4'd7 && write_sel[3] == 1'b1) ;
1581
            if(write_address == 4'd8 && write_sel[0] == 1'b1) bpl_con1 <= write_data[7:0];
1582
            if(write_address == 4'd8 && write_sel[1] == 1'b1) ;
1583
            if(write_address == 4'd8 && write_sel[2] == 1'b1) bpl_con0[2:0] <= write_data[19:17];
1584
            if(write_address == 4'd8 && write_sel[3] == 1'b1) bpl_con0[10:3] <= write_data[31:24];
1585
            if(write_address == 4'd9 && write_sel[0] == 1'b1) bpl_modulo[7:0] <= write_data[7:0];
1586
            if(write_address == 4'd9 && write_sel[1] == 1'b1) bpl_modulo[15:8] <= write_data[15:8];
1587
            if(write_address == 4'd9 && write_sel[2] == 1'b1) bpl_modulo[23:16] <= write_data[23:16];
1588
            if(write_address == 4'd9 && write_sel[3] == 1'b1) bpl_modulo[31:24] <= write_data[31:24];
1589
        end
1590
    end
1591
end
1592
 
1593
endmodule
1594
 
1595
/*! \brief Single bitplain module.
1596
 */
1597
module bitplain(
1598
    input CLK_I,
1599
    input reset_n,
1600
 
1601
    input line_start,
1602
    input [8:0] column_number,
1603
 
1604
    // video interface - read
1605
    input burst_read_enabled,
1606
        output reg burst_read_request,
1607
        output [31:2] burst_read_address,
1608
        input burst_read_ready,
1609
        input [31:0] burst_read_data,
1610
 
1611
    input write_ena,
1612
    // 0:   BPLxPTH,    BPLxPTL,
1613
    // 1:   BPLxDAT,    16'd0
1614
    input write_address,
1615
    input [31:0] write_data,
1616
    input [3:0] write_sel,
1617
 
1618
    input [10:0] bpl_con0,
1619
    input [3:0] bpl_delay,
1620
    input [15:0] bpl_modulo,
1621
    input [8:3] ddf_start,
1622
    input [8:3] ddf_stop,
1623
 
1624
    output color,
1625
 
1626
    input [8:0] line_number
1627
);
1628
 
1629
assign burst_read_address = dma_address_full[31:2];
1630
reg [31:0] dma_address_full;
1631
reg new_address;
1632
reg dma_started;
1633
 
1634
reg shift_delay;
1635
reg [5:0] shift_counter;
1636
reg [31:0] shift;
1637
assign color = shift[31];
1638
 
1639
reg [15:0] even_data;
1640
 
1641
reg [4:0] bitplain_ram_addr;
1642
wire [31:0] bitplain_ram_q;
1643
altsyncram bitplain_ram_inst(
1644
        .clock0(CLK_I),
1645
 
1646
        .address_a(bitplain_ram_addr),
1647
        .wren_a(burst_read_ready == 1'b1 && burst_read_request == 1'b1),
1648
        .data_a((dma_address_full[1] == 1'b0) ? burst_read_data : {even_data, burst_read_data[31:16]}),
1649
        .q_a(bitplain_ram_q)
1650
);
1651
defparam
1652
    bitplain_ram_inst.operation_mode = "SINGLE_PORT",
1653
    bitplain_ram_inst.width_a = 32,
1654
    bitplain_ram_inst.widthad_a = 5;
1655
 
1656
reg [1:0] dma_state;
1657
parameter [1:0]
1658
    DMA_DISABLED    = 2'd0,
1659
    DMA_ACTIVE      = 2'd1,
1660
    DMA_INACTIVE    = 2'd2;
1661
 
1662
// in multiples of 8, usually 38
1663
wire [8:3] ddf_diff;
1664
assign ddf_diff = ddf_stop[8:3] - ddf_start[8:3];
1665
 
1666
wire [8:3] ddf_stop_final;
1667
assign ddf_stop_final = (ddf_diff[3] == 1'b1)? ddf_stop + 6'd1 : ddf_stop;
1668
 
1669
wire [8:3] ddf_diff_final;
1670
assign ddf_diff_final = ddf_stop_final[8:3] - ddf_start[8:3];
1671
 
1672
// difference,  diff,   ram_addr
1673
// lowres
1674
// 0-7,         0,      0+1 >= 0 --> 1
1675
// 8-15,        2,      1+1 >= 0,2 --> 2
1676
// 16-23,       4,      2+1 >= 0,2 --> 2
1677
// 24-31,       6,      3+1 >= 0,2,4 --> 3
1678
// .....
1679
// 144-151,     36,     18+1 >= 0,2,4,6,8,10,12,14,16,18 --> 10
1680
// 152-159,     38,     19+1 >= 0,2,4,6,8,10,12,14,16,18,20 --> 11
1681
// hires
1682
// 0-3,         0,      0+2 >= 0,2 --> 2
1683
// 4-7,         1,      1+2 >= 0,2 --> 2
1684
// 8-11,        2,      2+2 >= 0,2,4 --> 3
1685
// 12-15,       3,      3+2 >= 0,2,4 --> 3
1686
// .....
1687
// 148-151,     37,     37+2 >= 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38 --> 20
1688
// 152-155,     38,     38+2 >= 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40 --> 21
1689
wire ddf_continue;
1690
assign ddf_continue =
1691
    (bpl_con0[10] == 1'b0 && { 1'b0, ddf_diff_final[8:4] } + 6'd1 >= { bitplain_ram_addr + 5'd1, 1'b0 } ) ||
1692
    (bpl_con0[10] == 1'b1 && ddf_diff_final[8:3] + 6'd2           >= { bitplain_ram_addr + 5'd1, 1'b0 } );
1693
 
1694
// lowres: 1C1 / 2 - 8.5 - 8 = D8 - 8 = D0,     x - 17 - 16 = {ddf_stop[8:3], 3'b0}
1695
// hires:  1C1 / 2 - 4.5 - 8 = DC - 8 = D4,     x - 9  - 16 = {ddf_stop[8:3], 3'b0}
1696
wire ddf_finished;
1697
assign ddf_finished =
1698
    (column_number > { ddf_stop_final[8:3], 3'b0 } + 9'd32) ||
1699
    (column_number == 9'd451);
1700
 
1701
always @(posedge CLK_I or negedge reset_n) begin
1702
    if(reset_n == 1'b0) begin
1703
        burst_read_request <= 1'b0;
1704
        dma_address_full <= 32'd0;
1705
        new_address <= 1'b0;
1706
        dma_started <= 1'b0;
1707
        shift_delay <= 1'b0;
1708
        shift_counter <= 6'd0;
1709
        shift <= 32'd0;
1710
        even_data <= 16'd0;
1711
        bitplain_ram_addr <= 5'd0;
1712
        dma_state <= DMA_DISABLED;
1713
    end
1714
    else begin
1715
        if(write_ena == 1'b1 && write_address == 1'b1 && write_sel[3:2] != 2'b00) begin
1716
            if(write_sel[3] == 1'b1) shift[31:24] <= write_data[31:24];
1717
            if(write_sel[2] == 1'b1) shift[23:16] <= write_data[23:16];
1718
        end
1719
        else if(dma_state == DMA_ACTIVE || dma_state == DMA_DISABLED) begin
1720
            shift <= 32'd0;
1721
            shift_delay <= 1'b0;
1722
            shift_counter <= 6'd32 + {1'b0, bpl_delay, 1'b0};
1723
            // delay in lowres pixels == 2 hires pixels == 0.5 color clock
1724
        end
1725
        else if(ddf_finished == 1'b1) begin
1726
            // ddf_stop in 2 lowres pixels == 4 hires pixels == 1.0 color clock
1727
            shift <= 32'd0;
1728
            shift_delay <= 1'b0;
1729
            shift_counter <= 6'd32;
1730
        end
1731
        else if(shift_delay == 1'b1) begin
1732
            shift_delay <= 1'b0;
1733
        end
1734
        else if((bpl_con0[10] == 1'b0 && column_number >= { ddf_start[8:3], 3'b0 } + 9'd17) ||
1735
                (bpl_con0[10] == 1'b1 && column_number >= { ddf_start[8:3], 3'b0 } + 9'd9))
1736
        begin
1737
            if(shift_counter > 6'd32) begin
1738
                shift_counter <= shift_counter - 6'd1;
1739
            end
1740
            else if(shift_counter == 6'd32) begin
1741
                if(bpl_con0[10] == 1'b0) shift_delay <= 1'b1; // HIRES==0
1742
                shift <= bitplain_ram_q;
1743
                shift_counter <= shift_counter - 6'd1;
1744
            end
1745
            else begin
1746
                if(bpl_con0[10] == 1'b0) shift_delay <= 1'b1; // HIRES==0
1747
                shift <= { shift[30:0], 1'b0 };
1748
 
1749
                if(shift_counter == 6'd1) shift_counter <= 6'd32;
1750
                else shift_counter <= shift_counter - 6'd1;
1751
            end
1752
        end
1753
 
1754
        if(burst_read_enabled == 1'b0) begin
1755
            bitplain_ram_addr <= 5'd0;
1756
            dma_state <= DMA_DISABLED;
1757
        end
1758
        else if(dma_state == DMA_DISABLED && line_start == 1'b1) begin
1759
            bitplain_ram_addr <= 5'd0;
1760
            dma_state <= DMA_ACTIVE;
1761
            burst_read_request <= 1'b1;
1762
            dma_started <= 1'b0;
1763
            new_address <= 1'b0;
1764
        end
1765
        else if(dma_state == DMA_ACTIVE && burst_read_ready == 1'b1) begin
1766
            if(ddf_continue == 1'b1) begin
1767
                if(dma_address_full[1] == 1'b0 || dma_started == 1'b1) bitplain_ram_addr <= bitplain_ram_addr + 5'd1;
1768
            end
1769
            else begin
1770
                bitplain_ram_addr <= 5'd0;
1771
                dma_state <= DMA_INACTIVE;
1772
                burst_read_request <= 1'b0;
1773
            end
1774
        end
1775
        else if(dma_state == DMA_INACTIVE && ddf_finished == 1'b1) begin
1776
            bitplain_ram_addr <= 5'd0;
1777
            dma_state <= DMA_DISABLED;
1778
        end
1779
        else if(dma_state == DMA_INACTIVE && shift_counter == 6'd2 && shift_delay == 1'b0) begin
1780
            bitplain_ram_addr <= bitplain_ram_addr + 5'd1;
1781
        end
1782
 
1783
        if(write_ena == 1'b1) begin
1784
            if(write_address == 1'b0 && write_sel[0] == 1'b1) dma_address_full[7:0] <= write_data[7:0];
1785
            if(write_address == 1'b0 && write_sel[1] == 1'b1) dma_address_full[15:8] <= write_data[15:8];
1786
            if(write_address == 1'b0 && write_sel[2] == 1'b1) dma_address_full[23:16] <= write_data[23:16];
1787
            if(write_address == 1'b0 && write_sel[3] == 1'b1) dma_address_full[31:24] <= write_data[31:24];
1788
            new_address <= 1'b1;
1789
        end
1790
        else if(dma_state == DMA_ACTIVE && burst_read_ready == 1'b1) begin
1791
            if(ddf_continue == 1'b0) begin
1792
                if(new_address == 1'b1)         dma_address_full <= dma_address_full;
1793
                else if(bpl_con0[10] == 1'b0)   dma_address_full <= dma_address_full + { {16{bpl_modulo[15]}}, bpl_modulo } + { { 1'b0, ddf_diff_final[8:4] } + 6'd1, 1'b0 };
1794
                else if(bpl_con0[10] == 1'b1)   dma_address_full <= dma_address_full + { {16{bpl_modulo[15]}}, bpl_modulo } + { ddf_diff_final[8:3] + 6'd2, 1'b0 };
1795
 
1796
                new_address <= 1'b0;
1797
            end
1798
 
1799
            dma_started <= 1'b1;
1800
            even_data <= burst_read_data[15:0];
1801
        end
1802
    end
1803
end
1804
 
1805
endmodule
1806
 
1807
/*! \brief Single sprite module.
1808
 */
1809
module sprite(
1810
    input CLK_I,
1811
    input reset_n,
1812
 
1813
    input line_start,
1814
    input [8:0] line_number,
1815
    input [8:0] column_number,
1816
 
1817
    input dma_ena,
1818
    output reg dma_req,
1819
    output [31:2] dma_address,
1820
    input dma_done,
1821
    input [31:0] dma_data,
1822
 
1823
    input write_ena,
1824
    // 0:   SPRxPTH,    SPRxPTL,
1825
    // 1:   SPRxPOS,    SPRxCTL,
1826
    // 2:   SPRxDATA,   SPRxDATB,
1827
    input [1:0] write_address,
1828
    input [31:0] write_data,
1829
    input [3:0] write_sel,
1830
 
1831
    output reg attached,
1832
    output [1:0] color
1833
);
1834
 
1835
// { SPRxPTH high 3 bits, SPRxPTL low 15 bits, lowest bit }
1836
reg [31:0] dma_address_full;
1837
assign dma_address = dma_address_full[31:2];
1838
reg dma_address_bit1;
1839
 
1840
// { SPRxDATB, SPRxDATA }
1841
reg [31:0] data;
1842
// { SPRxCTL[2], SPRxPOS[15:8] }
1843
reg [8:0] vert_start;
1844
// { SPRxCTL[1], SPRxCTL[15:8] }
1845
reg [8:0] vert_end;
1846
// { SPRxPOS[7:0], SPRxCTL[0] }
1847
reg [8:0] horiz_start;
1848
// SPRxCTL[7]
1849
// output reg attached
1850
 
1851
// disabled by write to SPRxCTL, enabled by write to SPRxDATA
1852
reg ena_horiz_comp;
1853
 
1854
reg shift_delay;
1855
reg [15:0] shiftA;
1856
reg [15:0] shiftB;
1857
assign color = { shiftA[15], shiftB[15] };
1858
 
1859
reg [1:0] dma_state;
1860
parameter [1:0]
1861
    DMA_DISABLED = 2'd0,
1862
    DMA_POS_CTL = 2'd1,
1863
    DMA_DAT = 2'd2;
1864
 
1865
always @(posedge CLK_I or negedge reset_n) begin
1866
    if(reset_n == 1'b0) begin
1867
        dma_req <= 1'b0;
1868
        dma_address_full <= 32'd0;
1869
        dma_address_bit1 <= 1'b0;
1870
        attached <= 1'b0;
1871
        data <= 32'd0;
1872
        vert_start <= 9'd0;
1873
        vert_end <= 9'd0;
1874
        horiz_start <= 9'd0;
1875
        ena_horiz_comp <= 1'b0;
1876
        shift_delay <= 1'b0;
1877
        shiftA <= 16'd0;
1878
        shiftB <= 16'd0;
1879
        dma_state <= DMA_DISABLED;
1880
    end
1881
    else begin
1882
        if(ena_horiz_comp == 1'b1 && horiz_start == column_number) begin
1883
            shift_delay <= 1'b0;
1884
            shiftA <= data[15:0];
1885
            shiftB <= data[31:16];
1886
        end
1887
        else if(shift_delay == 1'b1) begin
1888
            shift_delay <= 1'b0;
1889
        end
1890
        else begin
1891
            shift_delay <= 1'b1;
1892
            shiftA <= { shiftA[14:0], 1'b0 };
1893
            shiftB <= { shiftB[14:0], 1'b0 };
1894
        end
1895
 
1896
        if(         (write_ena == 1'b1 && write_address == 2'd1 && (write_sel[0] == 1'b1 || write_sel[1] == 1'b1)) ||
1897
                    (dma_done == 1'b1 && dma_state == DMA_POS_CTL) )    ena_horiz_comp <= 1'b0;
1898
        else if(    (write_ena == 1'b1 && write_address == 2'd2 && (write_sel[2] == 1'b1 || write_sel[3] == 1'b1)) ||
1899
                    (dma_done == 1'b1 && dma_state == DMA_DAT) )        ena_horiz_comp <= 1'b1;
1900
 
1901
        if(dma_ena == 1'b0 || (write_ena == 1'b1 && write_address == 2'd0 && write_sel[3:0] != 4'b0000)) begin
1902
            dma_state <= DMA_DISABLED;
1903
            dma_req <= 1'b0;
1904
            dma_address_bit1 <= 1'b0;
1905
        end
1906
        else if(dma_state != DMA_DISABLED && dma_done == 1'b1 && dma_address_full[1] == 1'b1 && dma_address_bit1 == 1'b0) begin
1907
            dma_req <= 1'b1;
1908
            dma_address_bit1 <= 1'b1;
1909
            dma_address_full <= dma_address_full + 19'd4;
1910
        end
1911
        else if(line_start == 1'b1 && (dma_state == DMA_DISABLED ||
1912
            (dma_state == DMA_DAT && line_number == vert_end && vert_start != vert_end)) )
1913
        begin
1914
            dma_state <= DMA_POS_CTL;
1915
            dma_req <= 1'b1;
1916
        end
1917
        else if(dma_done == 1'b1 && dma_state == DMA_POS_CTL) begin
1918
            dma_state <= DMA_DAT;
1919
            dma_req <= 1'b0;
1920
            if(dma_address_bit1 == 1'b0) dma_address_full <= dma_address_full + 19'd4;
1921
            dma_address_bit1 <= 1'b0;
1922
        end
1923
        else if(line_start == 1'b1 && dma_state == DMA_DAT && line_number >= vert_start && line_number < vert_end) begin
1924
            dma_req <= 1'b1;
1925
        end
1926
        else if(dma_done == 1'b1 && dma_state == DMA_DAT) begin
1927
            dma_req <= 1'b0;
1928
            if(dma_address_bit1 == 1'b0) dma_address_full <= dma_address_full + 19'd4;
1929
            dma_address_bit1 <= 1'b0;
1930
        end
1931
 
1932
        if(write_ena == 1'b1) begin
1933
            if(write_address == 2'd0 && write_sel[0] == 1'b1) dma_address_full[7:0] <= write_data[7:0];
1934
            if(write_address == 2'd0 && write_sel[1] == 1'b1) dma_address_full[15:8] <= write_data[15:8];
1935
            if(write_address == 2'd0 && write_sel[2] == 1'b1) dma_address_full[23:16] <= write_data[23:16];
1936
            if(write_address == 2'd0 && write_sel[3] == 1'b1) dma_address_full[31:24] <= write_data[31:24];
1937
            if(write_address == 2'd1 && write_sel[0] == 1'b1)
1938
                { attached, vert_start[8], vert_end[8], horiz_start[0]} <= { write_data[7], write_data[2:0] };
1939
            if(write_address == 2'd1 && write_sel[1] == 1'b1) vert_end[7:0] <= write_data[15:8];
1940
            if(write_address == 2'd1 && write_sel[2] == 1'b1) horiz_start[8:1] <= write_data[23:16];
1941
            if(write_address == 2'd1 && write_sel[3] == 1'b1) vert_start[7:0] <= write_data[31:24];
1942
            if(write_address == 2'd2 && write_sel[0] == 1'b1) data[7:0] <= write_data[7:0];
1943
            if(write_address == 2'd2 && write_sel[1] == 1'b1) data[15:8] <= write_data[15:8];
1944
            if(write_address == 2'd2 && write_sel[2] == 1'b1) data[23:16] <= write_data[23:16];
1945
            if(write_address == 2'd2 && write_sel[3] == 1'b1) data[31:24] <= write_data[31:24];
1946
        end
1947
        else if(dma_done == 1'b1) begin
1948
            if(dma_state == DMA_POS_CTL) begin
1949
                if(dma_address_full[1] == 1'b1 && dma_address_bit1 == 1'b0) begin
1950
                    horiz_start[8:1] <= dma_data[7:0];
1951
                    vert_start[7:0] <= dma_data[15:8];
1952
                end
1953
                else if(dma_address_full[1] == 1'b1 && dma_address_bit1 == 1'b1) begin
1954
                    { attached, vert_start[8], vert_end[8], horiz_start[0]} <= { dma_data[23], dma_data[18:16] };
1955
                    vert_end[7:0] <= dma_data[31:24];
1956
                end
1957
                else begin
1958
                    { attached, vert_start[8], vert_end[8], horiz_start[0]} <= { dma_data[7], dma_data[2:0] };
1959
                    vert_end[7:0]       <= dma_data[15:8];
1960
                    horiz_start[8:1]    <= dma_data[23:16];
1961
                    vert_start[7:0]     <= dma_data[31:24]; // vert_end*256 + horiz_start*2*655536 + vert_start*16777216
1962
                end
1963
            end
1964
            else if(dma_state == DMA_DAT) begin
1965
                if(dma_address_full[1] == 1'b1 && dma_address_bit1 == 1'b0) begin
1966
                    data[31:16] <= dma_data[15:0];
1967
                end
1968
                else if(dma_address_full[1] == 1'b1 && dma_address_bit1 == 1'b1) begin
1969
                    data[15:0] <= dma_data[31:16];
1970
                end
1971
                else begin
1972
                    data <= dma_data;
1973
                end
1974
            end
1975
        end
1976
    end
1977
end
1978
 
1979
endmodule
1980
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.