Subversion Repositories pentevo

Rev

Rev 674 | 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
200 lvd 2
//
3
// most of pentevo ports are here
4
 
668 lvd 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
 
30 lvd 24
`include "../include/tune.v"
25
 
4 lvd 26
module zports(
27
 
200 lvd 28
        input  wire        zclk,   // z80 clock
29
        input  wire        fclk,  // global FPGA clock
30
        input  wire        rst_n, // system reset
4 lvd 31
 
200 lvd 32
        input  wire        zpos,
33
        input  wire        zneg,
4 lvd 34
 
35
 
200 lvd 36
        input  wire [ 7:0] din,
37
        output reg  [ 7:0] dout,
38
        output wire        dataout,
39
        input  wire [15:0] a,
4 lvd 40
 
200 lvd 41
        input  wire        iorq_n,
42
        input  wire        mreq_n,
43
        input  wire        m1_n,
44
        input  wire        rd_n,
45
        input  wire        wr_n,
4 lvd 46
 
200 lvd 47
        output reg         porthit, // when internal port hit occurs, this is 1, else 0; used for iorq1_n iorq2_n on zxbus
467 lvd 48
        output reg         external_port, // asserts for AY and VG93 accesses
4 lvd 49
 
230 lvd 50
        output wire [15:0] ideout,
200 lvd 51
        input  wire [15:0] idein,
52
        output wire        idedataout, // IDE must IN data from IDE device when idedataout=0, else it OUTs
53
        output wire [ 2:0] ide_a,
54
        output wire        ide_cs0_n,
55
        output wire        ide_cs1_n,
56
        output wire        ide_rd_n,
57
        output wire        ide_wr_n,
4 lvd 58
 
59
 
200 lvd 60
        input  wire [ 4:0] keys_in, // keys (port FE)
61
        input  wire [ 7:0] mus_in,  // mouse (xxDF)
62
        input  wire [ 4:0] kj_in,
4 lvd 63
 
287 ddp 64
        output reg  [ 3:0] border,
4 lvd 65
 
284 lvd 66
 
200 lvd 67
        input  wire        dos,
4 lvd 68
 
69
 
200 lvd 70
        output wire        ay_bdir,
71
        output wire        ay_bc1,
4 lvd 72
 
200 lvd 73
        output wire [ 7:0] p7ffd,
74
        output wire [ 7:0] peff7,
4 lvd 75
 
213 lvd 76
        input  wire        tape_read,
77
 
200 lvd 78
        output wire        vg_cs_n,
79
        input  wire        vg_intrq,
80
        input  wire        vg_drq, // from vg93 module - drq + irq read
81
        output wire        vg_wrFF,        // write strobe of #FF port
88 lvd 82
 
543 lvd 83
        output wire        sd_cs_n_val,
84
        output wire        sd_cs_n_stb,
200 lvd 85
        output wire        sd_start,
86
        output wire [ 7:0] sd_datain,
87
        input  wire [ 7:0] sd_dataout,
88
 
228 lvd 89
        // WAIT-ports related
90
        //
88 lvd 91
        output reg  [ 7:0] gluclock_addr,
228 lvd 92
        //
93
        output reg  [ 2:0] comport_addr,
94
        //
88 lvd 95
        output wire        wait_start_gluclock, // begin wait from some ports
228 lvd 96
        output wire        wait_start_comport,  //
97
        //
88 lvd 98
        output reg         wait_rnw,   // whether it was read(=1) or write(=0)
99
        output reg  [ 7:0] wait_write,
200 lvd 100
        input  wire [ 7:0] wait_read,
101
 
102
 
103
        output wire        atmF7_wr_fclk, // used in atm_pager.v
104
 
105
 
106
        output reg  [ 2:0] atm_scr_mode, // RG0..RG2 in docs
107
        output reg         atm_turbo,    // turbo mode ON
108
        output reg         atm_pen,      // pager_off in atm_pager.v, NOT inverted!!!
109
        output reg         atm_cpm_n,    // permanent dos on
110
        output reg         atm_pen2,     // PEN2 - fucking palette mode, NOT inverted!!!
111
 
112
        output wire        romrw_en, // from port BF
113
 
114
 
115
        output wire        pent1m_ram0_0, // d3.eff7
116
        output wire        pent1m_1m_on,  // d2.eff7
117
        output wire [ 5:0] pent1m_page,   // full 1 meg page number
340 lvd 118
        output wire        pent1m_ROM,     // d4.7ffd
200 lvd 119
 
340 lvd 120
 
360 lvd 121
        output wire        atm_palwr,   // palette write strobe
122
        output wire [ 5:0] atm_paldata, // palette write data
340 lvd 123
 
360 lvd 124
        output wire        covox_wr,
394 tsl 125
        output wire        beeper_wr,
395 lvd 126
 
425 lvd 127
        output wire        clr_nmi,
395 lvd 128
 
425 lvd 129
        output wire        fnt_wr,              // write to font_ram enabled
130
 
131
        // inputs from atm_pagers, to read back its config
132
        input  wire [63:0] pages,
133
        input  wire [ 7:0] ramnroms,
134
        input  wire [ 7:0] dos7ffds,
674 lvd 135
        input  wire [ 7:0] wrdisables,
425 lvd 136
 
476 lvd 137
        input  wire [ 5:0] palcolor,
543 lvd 138
        input  wire [ 7:0] fontrom_readback,
476 lvd 139
 
668 lvd 140
        // ulaplus
141
        output reg         up_ena,
142
        output reg  [ 5:0] up_paladdr,
143
        output wire [ 7:0] up_paldata,
144
        output wire        up_palwr,
476 lvd 145
 
668 lvd 146
 
147
 
476 lvd 148
        // NMI generation
576 lvd 149
        output reg         set_nmi,
150
 
151
        // break enable & address
152
        output reg         brk_ena,
153
        output reg  [15:0] brk_addr
4 lvd 154
);
155
 
156
 
580 lvd 157
`define IS_NIDE_REGS(x) ( (x[2:0]==3'b000) && (x[3]!=x[4]) )
158
`define IS_NIDE_HIGH(x) ( x[7:0]==8'h11 )
159
`define IS_PORT_NIDE(x) ( `IS_NIDE_REGS(x) || `IS_NIDE_HIGH(x) )
160
`define NIDE_REGS 8'h10,8'h30,8'h50,8'h70,8'h90,8'hB0,8'hD0,8'hF0, \
161
                  8'h08,8'h28,8'h48,8'h68,8'h88,8'hA8,8'hC8,8'hE8
4 lvd 162
 
163
        localparam PORTFE = 8'hFE;
287 ddp 164
        localparam PORTF6 = 8'hF6;
4 lvd 165
        localparam PORTF7 = 8'hF7;
166
 
167
        localparam NIDE10 = 8'h10;
168
        localparam NIDE11 = 8'h11;
169
        localparam NIDE30 = 8'h30;
170
        localparam NIDE50 = 8'h50;
171
        localparam NIDE70 = 8'h70;
172
        localparam NIDE90 = 8'h90;
173
        localparam NIDEB0 = 8'hB0;
174
        localparam NIDED0 = 8'hD0;
175
        localparam NIDEF0 = 8'hF0;
176
        localparam NIDEC8 = 8'hC8;
177
 
178
        localparam PORTFD = 8'hFD;
179
 
180
        localparam VGCOM  = 8'h1F;
181
        localparam VGTRK  = 8'h3F;
182
        localparam VGSEC  = 8'h5F;
183
        localparam VGDAT  = 8'h7F;
184
        localparam VGSYS  = 8'hFF;
185
 
476 lvd 186
        localparam SAVPORT1 = 8'h2F;
187
        localparam SAVPORT2 = 8'h4F;
188
        localparam SAVPORT3 = 8'h6F;
189
        localparam SAVPORT4 = 8'h8F;
190
 
4 lvd 191
        localparam KJOY   = 8'h1F;
192
        localparam KMOUSE = 8'hDF;
193
 
194
        localparam SDCFG  = 8'h77;
195
        localparam SDDAT  = 8'h57;
196
 
200 lvd 197
        localparam ATMF7  = 8'hF7;
198
        localparam ATM77  = 8'h77;
4 lvd 199
 
425 lvd 200
        localparam ZXEVBE = 8'hBE; // xxBE config-read and nmi-end port
200 lvd 201
        localparam ZXEVBF = 8'hBF; // xxBF config port
582 lvd 202
        localparam ZXEVBRK = 8'hBD; // xxBD breakpoint address port     
200 lvd 203
 
228 lvd 204
        localparam COMPORT = 8'hEF; // F8EF..FFEF - rs232 ports
205
 
206
 
360 lvd 207
        localparam COVOX   = 8'hFB;
208
 
668 lvd 209
 
210
        localparam ULAPLUS = 8'h3B;
360 lvd 211
 
212
 
213
 
4 lvd 214
        reg port_wr;
215
        reg port_rd;
216
 
200 lvd 217
        reg iowr_reg;
218
        reg iord_reg;
4 lvd 219
 
200 lvd 220
 
221
        reg port_wr_fclk,
395 lvd 222
            port_rd_fclk,
223
            mem_wr_fclk;
200 lvd 224
 
225
        reg [1:0] iowr_reg_fclk,
226
                  iord_reg_fclk;
227
 
395 lvd 228
        reg [1:0] memwr_reg_fclk;
200 lvd 229
 
395 lvd 230
 
4 lvd 231
        wire [7:0] loa;
232
 
233
 
230 lvd 234
 
235
 
4 lvd 236
        wire ideout_hi_wr;
237
        wire idein_lo_rd;
230 lvd 238
        reg [7:0] idehiin; // IDE high part read register: low part is read directly to Z80 bus,
239
                           // while high part is remembered here
4 lvd 240
        reg ide_ports; // ide ports selected
241
 
230 lvd 242
        reg ide_rd_trig; // nemo-divide read trigger
243
        reg ide_rd_latch; // to save state of trigger during read cycle
244
 
245
        reg ide_wrlo_trig,  ide_wrhi_trig;  // nemo-divide write triggers
246
        reg ide_wrlo_latch, ide_wrhi_latch; // save state during write cycles
247
 
248
 
249
 
250
        reg  [15:0] idewrreg; // write register, either low or high part is pre-written here,
251
                              // while other part is out directly from Z80 bus
252
 
253
        wire [ 7:0] iderdeven; // to control read data from "even" ide ports (all except #11)
254
        wire [ 7:0] iderdodd;  // read data from "odd" port (#11)
255
 
256
 
257
 
4 lvd 258
        reg pre_bc1,pre_bdir;
259
 
88 lvd 260
        wire gluclock_on;
4 lvd 261
 
262
 
88 lvd 263
 
200 lvd 264
        reg  shadow_en_reg; //bit0.xxBF
265
        reg   romrw_en_reg; //bit1.xxBF
394 tsl 266
        reg  fntw_en_reg;       //bit2.xxBF
200 lvd 267
 
268
        wire shadow;
269
 
270
 
271
 
425 lvd 272
        reg [7:0] portbemux;
200 lvd 273
 
274
 
425 lvd 275
 
476 lvd 276
        reg [7:0] savport [3:0];
669 lvd 277
        reg [5:0] vgFF;
425 lvd 278
 
279
 
684 lvd 280
        reg [7:0] up_lastwritten;
476 lvd 281
 
282
 
200 lvd 283
        assign shadow = dos || shadow_en_reg;
284
 
285
 
286
 
287
 
288
 
289
 
4 lvd 290
        assign loa=a[7:0];
291
 
292
        always @*
293
        begin
287 ddp 294
                if( (loa==PORTFE) || (loa==PORTF6) ||
684 lvd 295
                    (loa==PORTFD) || (loa==8'hFC)  ||
4 lvd 296
 
580 lvd 297
                    `IS_PORT_NIDE(loa) ||
298
//                  (loa==NIDE10) || (loa==NIDE11) || (loa==NIDE30) || (loa==NIDE50) || (loa==NIDE70) ||
299
//                  (loa==NIDE90) || (loa==NIDEB0) || (loa==NIDED0) || (loa==NIDEF0) || (loa==NIDEC8) ||
4 lvd 300
 
200 lvd 301
                    (loa==KMOUSE) ||
4 lvd 302
 
200 lvd 303
                    ( (loa==VGCOM)&&shadow ) || ( (loa==VGTRK)&&shadow ) || ( (loa==VGSEC)&&shadow ) || ( (loa==VGDAT)&&shadow ) ||
304
                    ( (loa==VGSYS)&&shadow ) || ( (loa==KJOY)&&(!shadow) ) ||
305
 
476 lvd 306
                    ( (loa==SAVPORT1)&&shadow ) || ( (loa==SAVPORT2)&&shadow ) ||
307
                    ( (loa==SAVPORT3)&&shadow ) || ( (loa==SAVPORT4)&&shadow ) ||
308
 
309
 
228 lvd 310
                    ( (loa==PORTF7)&&(!shadow) ) || ( (loa==SDCFG)&&(!shadow) ) || ( (loa==SDDAT) ) ||
200 lvd 311
 
312
                    ( (loa==ATMF7)&&shadow ) || ( (loa==ATM77)&&shadow ) ||
313
 
668 lvd 314
                    ( loa==ZXEVBF ) || ( loa==ZXEVBE) || ( loa==ZXEVBRK) || ( loa==COMPORT ) ||
315
 
316
                    ( loa==ULAPLUS)
200 lvd 317
                  )
318
 
319
 
320
 
4 lvd 321
                        porthit = 1'b1;
322
                else
323
                        porthit = 1'b0;
324
        end
325
 
326
        always @*
327
        begin
543 lvd 328
                if( ((loa==PORTFD) && a[15]) || // 0xBFFD/0xFFFD ports
200 lvd 329
                    (( (loa==VGCOM)&&shadow ) || ( (loa==VGTRK)&&shadow ) || ( (loa==VGSEC)&&shadow ) || ( (loa==VGDAT)&&shadow )) ) // vg93 ports
4 lvd 330
                        external_port = 1'b1;
331
                else
332
                        external_port = 1'b0;
333
        end
334
 
335
        assign dataout = porthit & (~iorq_n) & (~rd_n) & (~external_port);
336
 
337
 
338
 
200 lvd 339
        // this is zclk-synchronous strobes
340
        always @(posedge zclk)
4 lvd 341
        begin
342
                iowr_reg <= ~(iorq_n | wr_n);
343
                iord_reg <= ~(iorq_n | rd_n);
344
 
345
                if( (!iowr_reg) && (!iorq_n) && (!wr_n) )
346
                        port_wr <= 1'b1;
347
                else
348
                        port_wr <= 1'b0;
349
 
350
 
351
                if( (!iord_reg) && (!iorq_n) && (!rd_n) )
352
                        port_rd <= 1'b1;
353
                else
354
                        port_rd <= 1'b0;
355
        end
356
 
357
 
200 lvd 358
 
359
 
360
        // fclk-synchronous stobes
361
        //
362
        always @(posedge fclk) if( zpos )
363
        begin
364
                iowr_reg_fclk[0] <= ~(iorq_n | wr_n);
365
                iord_reg_fclk[0] <= ~(iorq_n | rd_n);
366
        end
367
 
368
        always @(posedge fclk)
369
        begin
370
                iowr_reg_fclk[1] <= iowr_reg_fclk[0];
371
                iord_reg_fclk[1] <= iord_reg_fclk[0];
372
        end
373
 
374
        always @(posedge fclk)
375
        begin
376
                port_wr_fclk <= iowr_reg_fclk[0] && (!iowr_reg_fclk[1]);
377
                port_rd_fclk <= iord_reg_fclk[0] && (!iord_reg_fclk[1]);
378
        end
379
 
395 lvd 380
        always @(posedge fclk)
381
                memwr_reg_fclk[1:0] <= { memwr_reg_fclk[0], ~(mreq_n | wr_n) };
200 lvd 382
 
395 lvd 383
        always @(posedge fclk)
384
                mem_wr_fclk <= memwr_reg_fclk[0] && (!memwr_reg_fclk[1]);
200 lvd 385
 
386
 
387
 
4 lvd 388
        // dout data
389
        always @*
390
        begin
391
                case( loa )
392
                PORTFE:
213 lvd 393
                        dout = { 1'b1, tape_read, 1'b0, keys_in };
287 ddp 394
                PORTF6:
395
                        dout = { 1'b1, tape_read, 1'b0, keys_in };
4 lvd 396
 
397
 
580 lvd 398
                `NIDE_REGS:
230 lvd 399
                        dout = iderdeven;
4 lvd 400
                NIDE11:
230 lvd 401
                        dout = iderdodd;
4 lvd 402
 
403
 
404
                //PORTFD:
405
 
406
                VGSYS:
669 lvd 407
                        dout = { vg_intrq, vg_drq, vgFF }; // 6'b111111 };
4 lvd 408
 
476 lvd 409
                SAVPORT1, SAVPORT2, SAVPORT3, SAVPORT4:
410
                        dout = savport[ loa[6:5] ];
411
 
412
 
4 lvd 413
                KJOY:
110 lvd 414
                        dout = {3'b000, kj_in};
4 lvd 415
                KMOUSE:
67 lvd 416
                        dout = mus_in;
4 lvd 417
 
418
                SDCFG:
228 lvd 419
                        dout = 8'h00; // always SD inserted, SD is in R/W mode
4 lvd 420
                SDDAT:
421
                        dout = sd_dataout;
422
 
423
 
88 lvd 424
                PORTF7: begin
270 lvd 425
                        if( !a[14] && (a[8]^shadow) && gluclock_on ) // $BFF7 - data i/o
88 lvd 426
                                dout = wait_read;
427
                        else // any other $xxF7 port
428
                                dout = 8'hFF;
429
                end
430
 
228 lvd 431
                COMPORT: begin
432
                        dout = wait_read; // $F8EF..$FFEF
433
                end
88 lvd 434
 
425 lvd 435
                ZXEVBF: begin
576 lvd 436
                        dout = { 3'b000, brk_ena, set_nmi, fntw_en_reg, romrw_en_reg, shadow_en_reg };
425 lvd 437
                end
228 lvd 438
 
425 lvd 439
                ZXEVBE: begin
440
                        dout = portbemux;
441
                end
228 lvd 442
 
669 lvd 443
                ULAPLUS: begin
444
                        dout = up_lastwritten;
445
                end
425 lvd 446
 
669 lvd 447
 
4 lvd 448
                default:
449
                        dout = 8'hFF;
450
                endcase
451
        end
452
 
453
 
454
 
684 lvd 455
        assign portfd_wr    = ( (loa==PORTFD || loa==8'hFC) && port_wr);
4 lvd 456
 
270 lvd 457
        // F7 ports (like EFF7) are accessible in shadow mode but at addresses like EEF7, DEF7, BEF7 so that
458
        // there are no conflicts in shadow mode with ATM xFF7 and x7F7 ports
459
        assign portf7_wr    = ( (loa==PORTF7) && (a[8]==1'b1) && port_wr && (!shadow) ) ||
460
                              ( (loa==PORTF7) && (a[8]==1'b0) && port_wr &&   shadow  ) ;
461
 
462
        assign portf7_rd    = ( (loa==PORTF7) && (a[8]==1'b1) && port_rd && (!shadow) ) ||
463
                              ( (loa==PORTF7) && (a[8]==1'b0) && port_rd &&   shadow  ) ;
464
 
200 lvd 465
        assign vg_wrFF = ( ( (loa==VGSYS)&&shadow ) && port_wr);
669 lvd 466
        always @(posedge zclk) if( vg_wrFF )
467
                vgFF <= din[5:0];
4 lvd 468
 
228 lvd 469
        assign comport_wr   = ( (loa==COMPORT) && port_wr);
470
        assign comport_rd   = ( (loa==COMPORT) && port_rd);
4 lvd 471
 
576 lvd 472
 
473
        assign zxevbrk_wr_fclk = ( (loa==ZXEVBRK) && port_wr_fclk);
228 lvd 474
 
475
 
576 lvd 476
 
477
 
478
 
479
        // break address write
480
        always @(posedge fclk)
481
        if( zxevbrk_wr_fclk)
482
        begin
483
                if( !a[8] )
484
                        brk_addr[ 7:0] <= din;
485
                else // a[8]==1
486
                        brk_addr[15:8] <= din;
487
        end
488
 
489
 
490
 
491
 
492
 
360 lvd 493
        //border port FE
494
        wire portwe_wr_fclk;
4 lvd 495
 
684 lvd 496
        assign portfe_wr_fclk = (((loa==PORTFE) || (loa==PORTF6) || (loa==8'hFC)) && port_wr_fclk);
4 lvd 497
 
360 lvd 498
        always @(posedge fclk)
499
        if( portfe_wr_fclk )
500
                border <= { ~a[3], din[2:0] };
230 lvd 501
 
502
 
503
 
232 lvd 504
 
360 lvd 505
 
506
 
4 lvd 507
        // IDE ports
508
 
234 lvd 509
        // IDE physical ports (that go to IDE device)
510
        always @(loa)
580 lvd 511
        if( `IS_NIDE_REGS(loa) )
512
                ide_ports = 1'b1;
513
        else
514
                ide_ports = 1'b0;
228 lvd 515
 
234 lvd 516
 
517
        assign idein_lo_rd  = port_rd && (loa==NIDE10) && (!ide_rd_trig);
518
 
230 lvd 519
        // control read & write triggers, which allow nemo-divide mod to work.
234 lvd 520
        //
521
        // read trigger:
230 lvd 522
        always @(posedge zclk)
234 lvd 523
        begin
524
                if( (loa==NIDE10) && port_rd && !ide_rd_trig )
525
                        ide_rd_trig <= 1'b1;
526
                else if( ( ide_ports || (loa==NIDE11) ) && ( port_rd || port_wr ) )
527
                        ide_rd_trig <= 1'b0;
528
        end
235 lvd 529
        //
530
        // two triggers for write sequence...
234 lvd 531
        always @(posedge zclk)
235 lvd 532
        if( ( ide_ports || (loa==NIDE11) ) && ( port_rd || port_wr ) )
230 lvd 533
        begin
235 lvd 534
                if( (loa==NIDE11) && port_wr )
230 lvd 535
                        ide_wrhi_trig <= 1'b1;
235 lvd 536
                else
537
                        ide_wrhi_trig <= 1'b0;
230 lvd 538
                //
235 lvd 539
                if( (loa==NIDE10) && port_wr && !ide_wrhi_trig && !ide_wrlo_trig )
540
                        ide_wrlo_trig <= 1'b1;
541
                else
230 lvd 542
                        ide_wrlo_trig <= 1'b0;
543
        end
544
 
545
        // normal read: #10(low), #11(high)
546
        // divide read: #10(low), #10(high)
547
        //
548
        // normal write: #11(high), #10(low)
549
        // divide write: #10(low),  #10(high)
550
 
232 lvd 551
 
200 lvd 552
        always @(posedge zclk)
4 lvd 553
        begin
230 lvd 554
                if( port_wr && (loa==NIDE11) )
555
                        idewrreg[15:8] <= din;
4 lvd 556
 
243 lvd 557
                if( port_wr && (loa==NIDE10) && !ide_wrlo_trig )
230 lvd 558
                        idewrreg[ 7:0] <= din;
4 lvd 559
        end
560
 
230 lvd 561
 
562
 
563
 
564
        always @(posedge zclk)
565
        if( idein_lo_rd )
566
                        idehiin <= idein[15:8];
567
 
4 lvd 568
 
569
        assign ide_a = a[7:5];
230 lvd 570
 
571
 
572
        // This is unknown shit... Probably need more testing with old WD
573
        // drives WITHOUT this commented fix.
232 lvd 574
        //
4 lvd 575
        // trying to fix old WD drives...
230 lvd 576
        //assign ide_cs0_n = iorq_n | (rd_n&wr_n) | (~ide_ports) | (~(loa!=NIDEC8));
577
        //assign ide_cs1_n = iorq_n | (rd_n&wr_n) | (~ide_ports) | (~(loa==NIDEC8));
578
        // fix ends...
579
 
580
 
4 lvd 581
        assign ide_cs0_n = (~ide_ports) | (~(loa!=NIDEC8));
582
        assign ide_cs1_n = (~ide_ports) | (~(loa==NIDEC8));
230 lvd 583
 
584
 
585
        // generate read cycles for IDE as usual, except for reading #10
586
        // instead of #11 for high byte (nemo-divide). I use additional latch
587
        // since 'ide_rd_trig' clears during second Z80 IO read cycle to #10
588
        always @* if( rd_n ) ide_rd_latch <= ide_rd_trig;
589
        //
232 lvd 590
        assign ide_rd_n = iorq_n | rd_n | (~ide_ports) | (ide_rd_latch && (loa==NIDE10));
230 lvd 591
 
592
        always @* if( wr_n ) ide_wrlo_latch <= ide_wrlo_trig; // same for write triggers
593
        always @* if( wr_n ) ide_wrhi_latch <= ide_wrhi_trig; //
594
        //
595
        assign ide_wr_n = iorq_n | wr_n | (~ide_ports) | ( (loa==NIDE10) && !ide_wrlo_latch && !ide_wrhi_latch );
596
                                                  // do NOT generate IDE write, if neither of ide_wrhi|lo latches
597
                                                  // set and writing to NIDE10
598
 
599
 
600
 
526 lvd 601
//      assign idedataout = ide_rd_n;
602
        assign idedataout = ~ide_wr_n; // shit-fix in try to fix IDE errors
603
        // warning: this fix kinda blind-picking, good way is to
604
        // have idedataout lead wr or rd strobes. also good point to disable data ringing
605
        // on ide data bus while not accessing IDE
4 lvd 606
 
607
 
230 lvd 608
        // data read by Z80 from IDE
609
        //
610
        assign iderdodd[ 7:0] = idehiin[ 7:0];
611
        //
612
        assign iderdeven[ 7:0] = (ide_rd_latch && (loa==NIDE10)) ? idehiin[ 7:0] : idein[ 7:0];
613
 
614
        // data written to IDE from Z80
615
        //
233 lvd 616
        assign ideout[15:8] = ide_wrhi_latch ? idewrreg[15:8] : din[ 7:0];
617
        assign ideout[ 7:0] = ide_wrlo_latch ? idewrreg[ 7:0] : din[ 7:0];
230 lvd 618
 
619
 
620
 
621
 
622
 
623
 
624
 
4 lvd 625
        // AY control
626
        always @*
627
        begin
628
                pre_bc1 = 1'b0;
629
                pre_bdir = 1'b0;
630
 
631
                if( loa==PORTFD )
632
                begin
633
                        if( a[15:14]==2'b11 )
634
                        begin
635
                                pre_bc1=1'b1;
636
                                pre_bdir=1'b1;
637
                        end
638
                        else if( a[15:14]==2'b10 )
639
                        begin
640
                                pre_bc1=1'b0;
641
                                pre_bdir=1'b1;
642
                        end
643
                end
644
        end
645
 
646
        assign ay_bc1  = pre_bc1  & (~iorq_n) & ((~rd_n)|(~wr_n));
647
        assign ay_bdir = pre_bdir & (~iorq_n) & (~wr_n);
648
 
649
 
650
 
651
        // 7FFD port
652
        reg [7:0] p7ffd_int,peff7_int;
653
        reg p7ffd_rom_int;
654
        wire block7ffd;
655
        wire block1m;
656
 
200 lvd 657
        always @(posedge zclk, negedge rst_n)
4 lvd 658
        begin
659
                if( !rst_n )
660
                        p7ffd_int <= 7'h00;
661
                else if( (a[15]==1'b0) && portfd_wr && (!block7ffd) )
662
                        p7ffd_int <= din; // 2..0 - page, 3 - screen, 4 - rom, 5 - block48k, 6..7 -
663
        end
664
 
543 lvd 665
        always @(posedge zclk, negedge rst_n)
666
        if( !rst_n )
667
                        p7ffd_rom_int <= 1'b0;
668
        else
669
                if( (a[15]==1'b0) && portfd_wr && (!block7ffd) )
4 lvd 670
                        p7ffd_rom_int <= din[4];
671
 
543 lvd 672
 
4 lvd 673
        assign block7ffd=p7ffd_int[5] & block1m;
674
 
200 lvd 675
 
4 lvd 676
        // EFF7 port
200 lvd 677
        always @(posedge zclk, negedge rst_n)
4 lvd 678
        begin
679
                if( !rst_n )
680
                        peff7_int <= 8'h00;
284 lvd 681
                else if( !a[12] && portf7_wr && (!shadow) ) // EEF7 in shadow mode is abandoned!
4 lvd 682
                        peff7_int <= din; // 4 - turbooff, 0 - p16c on, 2 - block1meg
683
        end
684
        assign block1m = peff7_int[2];
685
 
39 ddp 686
        assign p7ffd = { (block1m ? 3'b0 : p7ffd_int[7:5]),p7ffd_rom_int,p7ffd_int[3:0]};
4 lvd 687
 
88 lvd 688
        assign peff7 = block1m ? { peff7_int[7], 1'b0, peff7_int[5], peff7_int[4], 3'b000, peff7_int[0] } : peff7_int;
4 lvd 689
 
690
 
200 lvd 691
        assign pent1m_ROM       = p7ffd_int[4];
692
        assign pent1m_page[5:0] = { p7ffd_int[7:5], p7ffd_int[2:0] };
693
        assign pent1m_1m_on     = ~peff7_int[2];
694
        assign pent1m_ram0_0    = peff7_int[3];
695
 
696
 
697
 
698
 
88 lvd 699
        // gluclock ports (bit7:eff7 is above)
4 lvd 700
 
284 lvd 701
        assign gluclock_on = peff7_int[7] || shadow; // in shadow mode EEF7 is abandoned: instead, gluclock access
702
                                                     // is ON forever in shadow mode.
88 lvd 703
 
200 lvd 704
        always @(posedge zclk)
88 lvd 705
        begin
706
                if( gluclock_on && portf7_wr ) // gluclocks on
707
                begin
708
                        if( !a[13] ) // $DFF7 - addr reg
709
                                gluclock_addr <= din;
710
 
711
                        // write to waiting register is not here - in separate section managing wait_write
712
                end
713
        end
714
 
715
 
228 lvd 716
        // comports
232 lvd 717
 
228 lvd 718
        always @(posedge zclk)
719
        begin
720
                if( comport_wr || comport_rd )
721
                        comport_addr <= a[10:8 ];
722
        end
88 lvd 723
 
724
 
725
 
726
        // write to wait registers
200 lvd 727
        always @(posedge zclk)
88 lvd 728
        begin
729
                // gluclocks
730
                if( gluclock_on && portf7_wr && !a[14] ) // $BFF7 - data reg
731
                        wait_write <= din;
228 lvd 732
                // com ports
733
                else if( comport_wr ) // $F8EF..$FFEF - comports
734
                        wait_write <= din;
88 lvd 735
        end
736
 
737
        // wait from wait registers
200 lvd 738
        //
739
        // ACHTUNG!!!! here portxx_wr are ON Z80 CLOCK! logic must change when moving to fclk strobes
740
        //
274 lvd 741
        assign wait_start_gluclock = ( gluclock_on && !a[14] && (portf7_rd || portf7_wr) ); // $BFF7 - gluclock r/w
228 lvd 742
        //
743
        assign wait_start_comport = ( comport_rd || comport_wr );
744
        //
745
        //
200 lvd 746
        always @(posedge zclk) // wait rnw - only meanful during wait
88 lvd 747
        begin
748
                if( port_wr )
749
                        wait_rnw <= 1'b0;
750
 
751
                if( port_rd )
752
                        wait_rnw <= 1'b1;
753
        end
754
 
755
 
756
 
757
 
758
 
4 lvd 759
        // VG93 control
200 lvd 760
        assign vg_cs_n =  (~shadow) | iorq_n | (rd_n & wr_n) | ( ~((loa==VGCOM)|(loa==VGTRK)|(loa==VGSEC)|(loa==VGDAT)) );
4 lvd 761
 
762
 
763
 
40 lvd 764
 
4 lvd 765
 
766
 
767
 
768
 
769
// SD card (z-control¸r compatible)
770
 
771
        wire sdcfg_wr,sddat_wr,sddat_rd;
772
 
467 lvd 773
        assign sdcfg_wr = ( (loa==SDCFG) && port_wr_fclk && (!shadow) )                  ||
774
                          ( (loa==SDDAT) && port_wr_fclk &&   shadow  && (a[15]==1'b1) ) ;
4 lvd 775
 
467 lvd 776
        assign sddat_wr = ( (loa==SDDAT) && port_wr_fclk && (!shadow) )                  ||
777
                          ( (loa==SDDAT) && port_wr_fclk &&   shadow  && (a[15]==1'b0) ) ;
228 lvd 778
 
467 lvd 779
        assign sddat_rd = ( (loa==SDDAT) && port_rd_fclk              );
228 lvd 780
 
4 lvd 781
        // SDCFG write - sdcs_n control
543 lvd 782
        assign sd_cs_n_stb = sdcfg_wr;
783
        assign sd_cs_n_val = din[1];
4 lvd 784
 
785
 
786
        // start signal for SPI module with resyncing to fclk
787
 
467 lvd 788
        assign sd_start = sddat_wr || sddat_rd;
4 lvd 789
 
790
        // data for SPI module
543 lvd 791
        assign sd_datain = sddat_rd ? 8'hFF : din;
4 lvd 792
 
793
 
794
 
200 lvd 795
 
796
 
797
 
798
 
799
/////////////////////////////////////////////////////////////////////////////////////////////////
800
 
801
        ///////////////
802
        // ATM ports //
803
        ///////////////
804
 
805
        wire atm77_wr_fclk;
806
        wire zxevbf_wr_fclk;
807
 
270 lvd 808
        assign atmF7_wr_fclk = ( (loa==ATMF7) && (a[8]==1'b1) && shadow && port_wr_fclk ); // xFF7 and x7F7 ports, NOT xEF7!
200 lvd 809
        assign atm77_wr_fclk = ( (loa==ATM77) && shadow && port_wr_fclk );
810
 
811
        assign zxevbf_wr_fclk = ( (loa==ZXEVBF) && port_wr_fclk );
812
 
813
 
814
        // port BF write
815
        //
816
        always @(posedge fclk, negedge rst_n)
817
        if( !rst_n )
818
        begin
476 lvd 819
                shadow_en_reg <= 1'b0;
820
                romrw_en_reg  <= 1'b0;
821
                fntw_en_reg   <= 1'b0;
822
                set_nmi       <= 1'b0;
576 lvd 823
                brk_ena       <= 1'b0;
200 lvd 824
        end
825
        else if( zxevbf_wr_fclk )
826
        begin
827
                shadow_en_reg <= din[0];
828
                romrw_en_reg  <= din[1];
394 tsl 829
                fntw_en_reg   <= din[2];
476 lvd 830
                set_nmi       <= din[3];
576 lvd 831
                brk_ena       <= din[4];
200 lvd 832
        end
833
 
834
        assign romrw_en = romrw_en_reg;
835
 
836
 
837
 
838
        // port xx77 write
839
        always @(posedge fclk, negedge rst_n)
840
        if( !rst_n )
841
        begin
842
                atm_scr_mode = 3'b011;
471 lvd 843
                atm_turbo    = 1'b0;
262 lvd 844
 
270 lvd 845
                atm_pen =   1'b1; // no manager,
846
                atm_cpm_n = 1'b0; // permanent dosen (shadow ports on)
262 lvd 847
 
848
 
200 lvd 849
                atm_pen2     = 1'b0;
850
        end
851
        else if( atm77_wr_fclk )
852
        begin
853
                atm_scr_mode <= din[2:0];
854
                atm_turbo    <= din[3];
855
                atm_pen      <= ~a[8];
856
                atm_cpm_n    <=  a[9];
857
                atm_pen2     <= ~a[14];
858
        end
859
 
860
 
340 lvd 861
        // atm palette strobe and data
360 lvd 862
        wire vg_wrFF_fclk;
200 lvd 863
 
360 lvd 864
        assign vg_wrFF_fclk = ( ( (loa==VGSYS)&&shadow ) && port_wr_fclk);
865
 
866
 
867
        assign atm_palwr = vg_wrFF_fclk & atm_pen2;
868
 
340 lvd 869
        assign atm_paldata = { ~din[4], ~din[7], ~din[1], ~din[6], ~din[0], ~din[5] };
870
 
360 lvd 871
 
872
 
425 lvd 873
        // port BE write
874
        assign clr_nmi = ( (loa==ZXEVBE) && port_wr_fclk );
360 lvd 875
 
876
 
877
 
425 lvd 878
 
360 lvd 879
        // covox/beeper writes
880
 
881
        assign beeper_wr = (loa==PORTFE) && portfe_wr_fclk;
882
        assign covox_wr  = (loa==COVOX) && port_wr_fclk;
883
 
884
 
395 lvd 885
 
886
        // font write enable
887
        assign fnt_wr = fntw_en_reg && mem_wr_fclk;
888
 
889
 
425 lvd 890
 
891
        // port BE read
892
 
893
        always @*
576 lvd 894
        case( a[12:8] )
425 lvd 895
 
576 lvd 896
        5'h0: portbemux = pages[ 7:0 ];
897
        5'h1: portbemux = pages[15:8 ];
898
        5'h2: portbemux = pages[23:16];
899
        5'h3: portbemux = pages[31:24];
900
        5'h4: portbemux = pages[39:32];
901
        5'h5: portbemux = pages[47:40];
902
        5'h6: portbemux = pages[55:48];
903
        5'h7: portbemux = pages[63:56];
425 lvd 904
 
576 lvd 905
        5'h8: portbemux = ramnroms;
906
        5'h9: portbemux = dos7ffds;
425 lvd 907
 
576 lvd 908
        5'hA: portbemux = p7ffd_int;
909
        5'hB: portbemux = peff7_int;
425 lvd 910
 
576 lvd 911
        5'hC: portbemux = { ~atm_pen2, atm_cpm_n, ~atm_pen, dos, atm_turbo, atm_scr_mode };
425 lvd 912
 
576 lvd 913
        5'hD: portbemux = { ~palcolor[4], ~palcolor[2], ~palcolor[0], ~palcolor[5], 2'b11, ~palcolor[3], ~palcolor[1] };
425 lvd 914
//      assign atm_paldata = { ~din[4], ~din[7], ~din[1], ~din[6], ~din[0], ~din[5] };
915
//  {GgRrBb} -> {grbG11RB}
916
// was: 76543210 -> 471605
917
// now:             543210 -> 4205xx31
918
 
576 lvd 919
        5'hE: portbemux = fontrom_readback;
669 lvd 920
        5'hF: portbemux = { 4'bXXXX, border };
543 lvd 921
 
576 lvd 922
        5'h10: portbemux = brk_addr[7:0];
923
        5'h11: portbemux = brk_addr[15:8];
543 lvd 924
 
674 lvd 925
        5'h12: portbemux = wrdisables;
926
 
425 lvd 927
        default: portbemux = 8'bXXXXXXXX;
928
 
929
        endcase
930
 
931
 
932
 
933
 
934
 
476 lvd 935
        // savelij ports write
936
        //
937
        always @(posedge fclk)
938
        if( port_wr_fclk && shadow )
939
        begin
940
                if( (loa==SAVPORT1) ||
941
                    (loa==SAVPORT2) ||
942
                    (loa==SAVPORT3) ||
943
                    (loa==SAVPORT4) )
944
                        savport[ loa[6:5] ] <= din;
945
        end
946
 
947
 
948
 
668 lvd 949
 
950
        // ULAPLUS ports
951
        reg up_select; // 0 -- ena/dis, 1 -- palette write
952
        //
953
        wire up_wr = port_wr_fclk && (loa==ULAPLUS);
954
        //
955
        always @(posedge fclk)
956
        if( up_wr && !a[14] )
957
        begin
958
                if( !din[7] &&  din[6] )
959
                begin
960
                        up_select <= 1'b1;
961
                end
962
 
963
                if( !din[7] && !din[6] )
964
                begin
965
                        up_select <= 1'b0;
966
                        up_paladdr[5:0] <= din[5:0];
967
                end
968
        end
969
        //
669 lvd 970
        always @(posedge fclk) if( up_wr && a[14] )
971
                up_lastwritten <= din;
972
        //
668 lvd 973
        assign up_palwr = up_wr && a[14] && !up_select;
974
        //
975
        always @(posedge fclk, negedge rst_n)
976
        if( !rst_n )
977
                up_ena <= 1'b0;
978
        else if( up_wr && a[14] && up_select )
979
                up_ena <= din[0];
980
        //
981
        assign up_paldata = {din[4:2],din[7:5],din[1:0]}; // G3R3B2 to R3G3B2
982
 
4 lvd 983
endmodule
200 lvd 984