Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
200 lvd 1
// PentEvo project (c) NedoPC 2008-2010
2
//
3
// most of pentevo ports are here
4
 
30 lvd 5
`include "../include/tune.v"
6
 
4 lvd 7
module zports(
8
 
200 lvd 9
        input  wire        zclk,   // z80 clock
10
        input  wire        fclk,  // global FPGA clock
11
        input  wire        rst_n, // system reset
4 lvd 12
 
200 lvd 13
        input  wire        zpos,
14
        input  wire        zneg,
4 lvd 15
 
16
 
200 lvd 17
        input  wire [ 7:0] din,
18
        output reg  [ 7:0] dout,
19
        output wire        dataout,
20
        input  wire [15:0] a,
4 lvd 21
 
200 lvd 22
        input  wire        iorq_n,
23
        input  wire        mreq_n,
24
        input  wire        m1_n,
25
        input  wire        rd_n,
26
        input  wire        wr_n,
4 lvd 27
 
200 lvd 28
        output reg         porthit, // when internal port hit occurs, this is 1, else 0; used for iorq1_n iorq2_n on zxbus
4 lvd 29
 
230 lvd 30
        output wire [15:0] ideout,
200 lvd 31
        input  wire [15:0] idein,
32
        output wire        idedataout, // IDE must IN data from IDE device when idedataout=0, else it OUTs
33
        output wire [ 2:0] ide_a,
34
        output wire        ide_cs0_n,
35
        output wire        ide_cs1_n,
36
        output wire        ide_rd_n,
37
        output wire        ide_wr_n,
4 lvd 38
 
39
 
200 lvd 40
        input  wire [ 4:0] keys_in, // keys (port FE)
41
        input  wire [ 7:0] mus_in,  // mouse (xxDF)
42
        input  wire [ 4:0] kj_in,
4 lvd 43
 
287 ddp 44
        output reg  [ 3:0] border,
4 lvd 45
 
284 lvd 46
        output reg         beeper,
47
        output reg         tapeout,
48
 
200 lvd 49
        input  wire        dos,
4 lvd 50
 
51
 
200 lvd 52
        output wire        ay_bdir,
53
        output wire        ay_bc1,
4 lvd 54
 
200 lvd 55
        output wire [ 7:0] p7ffd,
56
        output wire [ 7:0] peff7,
4 lvd 57
 
200 lvd 58
        input  wire [ 1:0] rstrom,
4 lvd 59
 
213 lvd 60
        input  wire        tape_read,
61
 
200 lvd 62
        output wire        vg_cs_n,
63
        input  wire        vg_intrq,
64
        input  wire        vg_drq, // from vg93 module - drq + irq read
65
        output wire        vg_wrFF,        // write strobe of #FF port
88 lvd 66
 
200 lvd 67
        output reg         sdcs_n,
68
        output wire        sd_start,
69
        output wire [ 7:0] sd_datain,
70
        input  wire [ 7:0] sd_dataout,
71
 
228 lvd 72
        // WAIT-ports related
73
        //
88 lvd 74
        output reg  [ 7:0] gluclock_addr,
228 lvd 75
        //
76
        output reg  [ 2:0] comport_addr,
77
        //
88 lvd 78
        output wire        wait_start_gluclock, // begin wait from some ports
228 lvd 79
        output wire        wait_start_comport,  //
80
        //
88 lvd 81
        output reg         wait_rnw,   // whether it was read(=1) or write(=0)
82
        output reg  [ 7:0] wait_write,
200 lvd 83
        input  wire [ 7:0] wait_read,
84
 
85
 
86
        output wire        atmF7_wr_fclk, // used in atm_pager.v
87
 
88
 
89
        output reg  [ 2:0] atm_scr_mode, // RG0..RG2 in docs
90
        output reg         atm_turbo,    // turbo mode ON
91
        output reg         atm_pen,      // pager_off in atm_pager.v, NOT inverted!!!
92
        output reg         atm_cpm_n,    // permanent dos on
93
        output reg         atm_pen2,     // PEN2 - fucking palette mode, NOT inverted!!!
94
 
95
        output wire        romrw_en, // from port BF
96
 
97
 
98
        output wire        pent1m_ram0_0, // d3.eff7
99
        output wire        pent1m_1m_on,  // d2.eff7
100
        output wire [ 5:0] pent1m_page,   // full 1 meg page number
101
        output wire        pent1m_ROM     // d4.7ffd
102
 
4 lvd 103
);
104
 
105
 
106
        reg rstsync1,rstsync2;
107
 
108
 
109
        localparam PORTFE = 8'hFE;
287 ddp 110
        localparam PORTF6 = 8'hF6;
4 lvd 111
        localparam PORTF7 = 8'hF7;
112
 
113
        localparam NIDE10 = 8'h10;
114
        localparam NIDE11 = 8'h11;
115
        localparam NIDE30 = 8'h30;
116
        localparam NIDE50 = 8'h50;
117
        localparam NIDE70 = 8'h70;
118
        localparam NIDE90 = 8'h90;
119
        localparam NIDEB0 = 8'hB0;
120
        localparam NIDED0 = 8'hD0;
121
        localparam NIDEF0 = 8'hF0;
122
        localparam NIDEC8 = 8'hC8;
123
 
124
        localparam PORTFD = 8'hFD;
125
 
126
        localparam VGCOM  = 8'h1F;
127
        localparam VGTRK  = 8'h3F;
128
        localparam VGSEC  = 8'h5F;
129
        localparam VGDAT  = 8'h7F;
130
        localparam VGSYS  = 8'hFF;
131
 
132
        localparam KJOY   = 8'h1F;
133
        localparam KMOUSE = 8'hDF;
134
 
135
        localparam SDCFG  = 8'h77;
136
        localparam SDDAT  = 8'h57;
137
 
200 lvd 138
        localparam ATMF7  = 8'hF7;
139
        localparam ATM77  = 8'h77;
4 lvd 140
 
200 lvd 141
        localparam ZXEVBF = 8'hBF; // xxBF config port
142
 
228 lvd 143
        localparam COMPORT = 8'hEF; // F8EF..FFEF - rs232 ports
144
 
145
 
4 lvd 146
        reg external_port;
147
 
148
        reg port_wr;
149
        reg port_rd;
150
 
200 lvd 151
        reg iowr_reg;
152
        reg iord_reg;
4 lvd 153
 
200 lvd 154
 
155
        reg port_wr_fclk,
156
            port_rd_fclk;
157
 
158
        reg [1:0] iowr_reg_fclk,
159
                  iord_reg_fclk;
160
 
161
 
4 lvd 162
        wire [7:0] loa;
163
 
164
        wire portfe_wr;
165
 
230 lvd 166
 
167
 
4 lvd 168
        wire ideout_hi_wr;
169
        wire idein_lo_rd;
230 lvd 170
        reg [7:0] idehiin; // IDE high part read register: low part is read directly to Z80 bus,
171
                           // while high part is remembered here
4 lvd 172
        reg ide_ports; // ide ports selected
173
 
230 lvd 174
        reg ide_rd_trig; // nemo-divide read trigger
175
        reg ide_rd_latch; // to save state of trigger during read cycle
176
 
177
        reg ide_wrlo_trig,  ide_wrhi_trig;  // nemo-divide write triggers
178
        reg ide_wrlo_latch, ide_wrhi_latch; // save state during write cycles
179
 
180
 
181
 
182
        reg  [15:0] idewrreg; // write register, either low or high part is pre-written here,
183
                              // while other part is out directly from Z80 bus
184
 
185
        wire [ 7:0] iderdeven; // to control read data from "even" ide ports (all except #11)
186
        wire [ 7:0] iderdodd;  // read data from "odd" port (#11)
187
 
188
 
189
 
4 lvd 190
        reg pre_bc1,pre_bdir;
191
 
88 lvd 192
        wire gluclock_on;
4 lvd 193
 
194
 
88 lvd 195
 
200 lvd 196
        reg  shadow_en_reg; //bit0.xxBF
197
        reg   romrw_en_reg; //bit1.xxBF
198
 
199
        wire shadow;
200
 
201
 
202
 
203
 
204
 
205
        assign shadow = dos || shadow_en_reg;
206
 
207
 
208
 
209
 
210
 
211
 
4 lvd 212
        assign loa=a[7:0];
213
 
214
        always @*
215
        begin
287 ddp 216
                if( (loa==PORTFE) || (loa==PORTF6) ||
200 lvd 217
                    (loa==PORTFD) ||
4 lvd 218
 
200 lvd 219
                    (loa==NIDE10) || (loa==NIDE11) || (loa==NIDE30) || (loa==NIDE50) || (loa==NIDE70) ||
220
                    (loa==NIDE90) || (loa==NIDEB0) || (loa==NIDED0) || (loa==NIDEF0) || (loa==NIDEC8) ||
4 lvd 221
 
200 lvd 222
                    (loa==KMOUSE) ||
4 lvd 223
 
200 lvd 224
                    ( (loa==VGCOM)&&shadow ) || ( (loa==VGTRK)&&shadow ) || ( (loa==VGSEC)&&shadow ) || ( (loa==VGDAT)&&shadow ) ||
225
                    ( (loa==VGSYS)&&shadow ) || ( (loa==KJOY)&&(!shadow) ) ||
226
 
228 lvd 227
                    ( (loa==PORTF7)&&(!shadow) ) || ( (loa==SDCFG)&&(!shadow) ) || ( (loa==SDDAT) ) ||
200 lvd 228
 
229
                    ( (loa==ATMF7)&&shadow ) || ( (loa==ATM77)&&shadow ) ||
230
 
228 lvd 231
                    ( loa==ZXEVBF ) || ( loa==COMPORT )
200 lvd 232
                  )
233
 
234
 
235
 
4 lvd 236
                        porthit = 1'b1;
237
                else
238
                        porthit = 1'b0;
239
        end
240
 
241
        always @*
242
        begin
243
                if( ((loa==PORTFD) && (a[15:14]==2'b11)) || // 0xFFFD ports
200 lvd 244
                    (( (loa==VGCOM)&&shadow ) || ( (loa==VGTRK)&&shadow ) || ( (loa==VGSEC)&&shadow ) || ( (loa==VGDAT)&&shadow )) ) // vg93 ports
4 lvd 245
                        external_port = 1'b1;
246
                else
247
                        external_port = 1'b0;
248
        end
249
 
250
        assign dataout = porthit & (~iorq_n) & (~rd_n) & (~external_port);
251
 
252
 
253
 
200 lvd 254
        // this is zclk-synchronous strobes
255
        always @(posedge zclk)
4 lvd 256
        begin
257
                iowr_reg <= ~(iorq_n | wr_n);
258
                iord_reg <= ~(iorq_n | rd_n);
259
 
260
                if( (!iowr_reg) && (!iorq_n) && (!wr_n) )
261
                        port_wr <= 1'b1;
262
                else
263
                        port_wr <= 1'b0;
264
 
265
 
266
                if( (!iord_reg) && (!iorq_n) && (!rd_n) )
267
                        port_rd <= 1'b1;
268
                else
269
                        port_rd <= 1'b0;
270
        end
271
 
272
 
200 lvd 273
 
274
 
275
        // fclk-synchronous stobes
276
        //
277
        always @(posedge fclk) if( zpos )
278
        begin
279
                iowr_reg_fclk[0] <= ~(iorq_n | wr_n);
280
                iord_reg_fclk[0] <= ~(iorq_n | rd_n);
281
        end
282
 
283
        always @(posedge fclk)
284
        begin
285
                iowr_reg_fclk[1] <= iowr_reg_fclk[0];
286
                iord_reg_fclk[1] <= iord_reg_fclk[0];
287
        end
288
 
289
        always @(posedge fclk)
290
        begin
291
                port_wr_fclk <= iowr_reg_fclk[0] && (!iowr_reg_fclk[1]);
292
                port_rd_fclk <= iord_reg_fclk[0] && (!iord_reg_fclk[1]);
293
        end
294
 
295
 
296
 
297
 
298
 
4 lvd 299
        // dout data
300
        always @*
301
        begin
302
                case( loa )
303
                PORTFE:
213 lvd 304
                        dout = { 1'b1, tape_read, 1'b0, keys_in };
287 ddp 305
                PORTF6:
306
                        dout = { 1'b1, tape_read, 1'b0, keys_in };
4 lvd 307
 
308
 
309
                NIDE10,NIDE30,NIDE50,NIDE70,NIDE90,NIDEB0,NIDED0,NIDEF0,NIDEC8:
230 lvd 310
                        dout = iderdeven;
4 lvd 311
                NIDE11:
230 lvd 312
                        dout = iderdodd;
4 lvd 313
 
314
 
315
                //PORTFD:
316
 
317
                VGSYS:
318
                        dout = { vg_intrq, vg_drq, 6'b111111 };
319
 
320
                KJOY:
110 lvd 321
                        dout = {3'b000, kj_in};
4 lvd 322
                KMOUSE:
67 lvd 323
                        dout = mus_in;
4 lvd 324
 
325
                SDCFG:
228 lvd 326
                        dout = 8'h00; // always SD inserted, SD is in R/W mode
4 lvd 327
                SDDAT:
328
                        dout = sd_dataout;
329
 
330
 
88 lvd 331
                PORTF7: begin
270 lvd 332
                        if( !a[14] && (a[8]^shadow) && gluclock_on ) // $BFF7 - data i/o
88 lvd 333
                                dout = wait_read;
334
                        else // any other $xxF7 port
335
                                dout = 8'hFF;
336
                end
337
 
228 lvd 338
                COMPORT: begin
339
                        dout = wait_read; // $F8EF..$FFEF
340
                end
88 lvd 341
 
228 lvd 342
 
343
 
4 lvd 344
                default:
345
                        dout = 8'hFF;
346
                endcase
347
        end
348
 
349
 
350
 
287 ddp 351
        assign portfe_wr    = (((loa==PORTFE) || (loa==PORTF6)) && port_wr);
4 lvd 352
        assign portfd_wr    = ( (loa==PORTFD) && port_wr);
353
 
270 lvd 354
        // F7 ports (like EFF7) are accessible in shadow mode but at addresses like EEF7, DEF7, BEF7 so that
355
        // there are no conflicts in shadow mode with ATM xFF7 and x7F7 ports
356
        assign portf7_wr    = ( (loa==PORTF7) && (a[8]==1'b1) && port_wr && (!shadow) ) ||
357
                              ( (loa==PORTF7) && (a[8]==1'b0) && port_wr &&   shadow  ) ;
358
 
359
        assign portf7_rd    = ( (loa==PORTF7) && (a[8]==1'b1) && port_rd && (!shadow) ) ||
360
                              ( (loa==PORTF7) && (a[8]==1'b0) && port_rd &&   shadow  ) ;
361
 
200 lvd 362
        assign vg_wrFF = ( ( (loa==VGSYS)&&shadow ) && port_wr);
4 lvd 363
 
228 lvd 364
        assign comport_wr   = ( (loa==COMPORT) && port_wr);
365
        assign comport_rd   = ( (loa==COMPORT) && port_rd);
4 lvd 366
 
228 lvd 367
 
368
 
4 lvd 369
        //port FE beep/border bit
200 lvd 370
        always @(posedge zclk)
4 lvd 371
        begin
372
                if( portfe_wr )
373
                begin
284 lvd 374
                        tapeout <= din[3];
375
                        beeper  <= din[4];
287 ddp 376
                        border <= { ~a[3], din[2:0] };
4 lvd 377
                end
378
        end
379
 
380
 
230 lvd 381
 
382
 
383
 
232 lvd 384
 
4 lvd 385
        // IDE ports
386
 
234 lvd 387
        // IDE physical ports (that go to IDE device)
388
        always @(loa)
389
                case( loa )
390
                NIDE10,NIDE30,NIDE50,NIDE70,NIDE90,NIDEB0,NIDED0,NIDEF0,NIDEC8: ide_ports = 1'b1;
391
                default: ide_ports = 1'b0;
392
                endcase
228 lvd 393
 
234 lvd 394
 
395
        assign idein_lo_rd  = port_rd && (loa==NIDE10) && (!ide_rd_trig);
396
 
230 lvd 397
        // control read & write triggers, which allow nemo-divide mod to work.
234 lvd 398
        //
399
        // read trigger:
230 lvd 400
        always @(posedge zclk)
234 lvd 401
        begin
402
                if( (loa==NIDE10) && port_rd && !ide_rd_trig )
403
                        ide_rd_trig <= 1'b1;
404
                else if( ( ide_ports || (loa==NIDE11) ) && ( port_rd || port_wr ) )
405
                        ide_rd_trig <= 1'b0;
406
        end
235 lvd 407
        //
408
        // two triggers for write sequence...
234 lvd 409
        always @(posedge zclk)
235 lvd 410
        if( ( ide_ports || (loa==NIDE11) ) && ( port_rd || port_wr ) )
230 lvd 411
        begin
235 lvd 412
                if( (loa==NIDE11) && port_wr )
230 lvd 413
                        ide_wrhi_trig <= 1'b1;
235 lvd 414
                else
415
                        ide_wrhi_trig <= 1'b0;
230 lvd 416
                //
235 lvd 417
                if( (loa==NIDE10) && port_wr && !ide_wrhi_trig && !ide_wrlo_trig )
418
                        ide_wrlo_trig <= 1'b1;
419
                else
230 lvd 420
                        ide_wrlo_trig <= 1'b0;
421
        end
422
 
423
        // normal read: #10(low), #11(high)
424
        // divide read: #10(low), #10(high)
425
        //
426
        // normal write: #11(high), #10(low)
427
        // divide write: #10(low),  #10(high)
428
 
232 lvd 429
 
200 lvd 430
        always @(posedge zclk)
4 lvd 431
        begin
230 lvd 432
                if( port_wr && (loa==NIDE11) )
433
                        idewrreg[15:8] <= din;
4 lvd 434
 
243 lvd 435
                if( port_wr && (loa==NIDE10) && !ide_wrlo_trig )
230 lvd 436
                        idewrreg[ 7:0] <= din;
4 lvd 437
        end
438
 
230 lvd 439
 
440
 
441
 
442
        always @(posedge zclk)
443
        if( idein_lo_rd )
444
                        idehiin <= idein[15:8];
445
 
4 lvd 446
 
447
        assign ide_a = a[7:5];
230 lvd 448
 
449
 
450
        // This is unknown shit... Probably need more testing with old WD
451
        // drives WITHOUT this commented fix.
232 lvd 452
        //
4 lvd 453
        // trying to fix old WD drives...
230 lvd 454
        //assign ide_cs0_n = iorq_n | (rd_n&wr_n) | (~ide_ports) | (~(loa!=NIDEC8));
455
        //assign ide_cs1_n = iorq_n | (rd_n&wr_n) | (~ide_ports) | (~(loa==NIDEC8));
456
        // fix ends...
457
 
458
 
4 lvd 459
        assign ide_cs0_n = (~ide_ports) | (~(loa!=NIDEC8));
460
        assign ide_cs1_n = (~ide_ports) | (~(loa==NIDEC8));
230 lvd 461
 
462
 
463
        // generate read cycles for IDE as usual, except for reading #10
464
        // instead of #11 for high byte (nemo-divide). I use additional latch
465
        // since 'ide_rd_trig' clears during second Z80 IO read cycle to #10
466
        always @* if( rd_n ) ide_rd_latch <= ide_rd_trig;
467
        //
232 lvd 468
        assign ide_rd_n = iorq_n | rd_n | (~ide_ports) | (ide_rd_latch && (loa==NIDE10));
230 lvd 469
 
470
        always @* if( wr_n ) ide_wrlo_latch <= ide_wrlo_trig; // same for write triggers
471
        always @* if( wr_n ) ide_wrhi_latch <= ide_wrhi_trig; //
472
        //
473
        assign ide_wr_n = iorq_n | wr_n | (~ide_ports) | ( (loa==NIDE10) && !ide_wrlo_latch && !ide_wrhi_latch );
474
                                                  // do NOT generate IDE write, if neither of ide_wrhi|lo latches
475
                                                  // set and writing to NIDE10
476
 
477
 
478
 
4 lvd 479
        assign idedataout = ide_rd_n;
480
 
481
 
230 lvd 482
 
483
        // data read by Z80 from IDE
484
        //
485
        assign iderdodd[ 7:0] = idehiin[ 7:0];
486
        //
487
        assign iderdeven[ 7:0] = (ide_rd_latch && (loa==NIDE10)) ? idehiin[ 7:0] : idein[ 7:0];
488
 
489
        // data written to IDE from Z80
490
        //
233 lvd 491
        assign ideout[15:8] = ide_wrhi_latch ? idewrreg[15:8] : din[ 7:0];
492
        assign ideout[ 7:0] = ide_wrlo_latch ? idewrreg[ 7:0] : din[ 7:0];
230 lvd 493
 
494
 
495
 
496
 
497
 
498
 
499
 
4 lvd 500
        // AY control
501
        always @*
502
        begin
503
                pre_bc1 = 1'b0;
504
                pre_bdir = 1'b0;
505
 
506
                if( loa==PORTFD )
507
                begin
508
                        if( a[15:14]==2'b11 )
509
                        begin
510
                                pre_bc1=1'b1;
511
                                pre_bdir=1'b1;
512
                        end
513
                        else if( a[15:14]==2'b10 )
514
                        begin
515
                                pre_bc1=1'b0;
516
                                pre_bdir=1'b1;
517
                        end
518
                end
519
        end
520
 
521
        assign ay_bc1  = pre_bc1  & (~iorq_n) & ((~rd_n)|(~wr_n));
522
        assign ay_bdir = pre_bdir & (~iorq_n) & (~wr_n);
523
 
524
 
525
 
526
        // 7FFD port
527
        reg [7:0] p7ffd_int,peff7_int;
528
        reg p7ffd_rom_int;
529
        wire block7ffd;
530
        wire block1m;
531
 
200 lvd 532
        always @(posedge zclk, negedge rst_n)
4 lvd 533
        begin
534
                if( !rst_n )
535
                        p7ffd_int <= 7'h00;
536
                else if( (a[15]==1'b0) && portfd_wr && (!block7ffd) )
537
                        p7ffd_int <= din; // 2..0 - page, 3 - screen, 4 - rom, 5 - block48k, 6..7 -
538
        end
539
 
200 lvd 540
        always @(posedge zclk)
4 lvd 541
        begin
542
                if( rstsync2 )
543
                        p7ffd_rom_int <= rstrom[0];
544
                else if( (a[15]==1'b0) && portfd_wr && (!block7ffd) )
545
                        p7ffd_rom_int <= din[4];
546
        end
547
 
548
        assign block7ffd=p7ffd_int[5] & block1m;
549
 
200 lvd 550
 
4 lvd 551
        // EFF7 port
200 lvd 552
        always @(posedge zclk, negedge rst_n)
4 lvd 553
        begin
554
                if( !rst_n )
555
                        peff7_int <= 8'h00;
284 lvd 556
                else if( !a[12] && portf7_wr && (!shadow) ) // EEF7 in shadow mode is abandoned!
4 lvd 557
                        peff7_int <= din; // 4 - turbooff, 0 - p16c on, 2 - block1meg
558
        end
559
        assign block1m = peff7_int[2];
560
 
39 ddp 561
        assign p7ffd = { (block1m ? 3'b0 : p7ffd_int[7:5]),p7ffd_rom_int,p7ffd_int[3:0]};
4 lvd 562
 
88 lvd 563
        assign peff7 = block1m ? { peff7_int[7], 1'b0, peff7_int[5], peff7_int[4], 3'b000, peff7_int[0] } : peff7_int;
4 lvd 564
 
565
 
200 lvd 566
        assign pent1m_ROM       = p7ffd_int[4];
567
        assign pent1m_page[5:0] = { p7ffd_int[7:5], p7ffd_int[2:0] };
568
        assign pent1m_1m_on     = ~peff7_int[2];
569
        assign pent1m_ram0_0    = peff7_int[3];
570
 
571
 
572
 
573
 
88 lvd 574
        // gluclock ports (bit7:eff7 is above)
4 lvd 575
 
284 lvd 576
        assign gluclock_on = peff7_int[7] || shadow; // in shadow mode EEF7 is abandoned: instead, gluclock access
577
                                                     // is ON forever in shadow mode.
88 lvd 578
 
200 lvd 579
        always @(posedge zclk)
88 lvd 580
        begin
581
                if( gluclock_on && portf7_wr ) // gluclocks on
582
                begin
583
                        if( !a[13] ) // $DFF7 - addr reg
584
                                gluclock_addr <= din;
585
 
586
                        // write to waiting register is not here - in separate section managing wait_write
587
                end
588
        end
589
 
590
 
228 lvd 591
        // comports
232 lvd 592
 
228 lvd 593
        always @(posedge zclk)
594
        begin
595
                if( comport_wr || comport_rd )
596
                        comport_addr <= a[10:8 ];
597
        end
88 lvd 598
 
599
 
600
 
601
        // write to wait registers
200 lvd 602
        always @(posedge zclk)
88 lvd 603
        begin
604
                // gluclocks
605
                if( gluclock_on && portf7_wr && !a[14] ) // $BFF7 - data reg
606
                        wait_write <= din;
228 lvd 607
                // com ports
608
                else if( comport_wr ) // $F8EF..$FFEF - comports
609
                        wait_write <= din;
88 lvd 610
        end
611
 
612
        // wait from wait registers
200 lvd 613
        //
614
        // ACHTUNG!!!! here portxx_wr are ON Z80 CLOCK! logic must change when moving to fclk strobes
615
        //
274 lvd 616
        assign wait_start_gluclock = ( gluclock_on && !a[14] && (portf7_rd || portf7_wr) ); // $BFF7 - gluclock r/w
228 lvd 617
        //
618
        assign wait_start_comport = ( comport_rd || comport_wr );
619
        //
620
        //
200 lvd 621
        always @(posedge zclk) // wait rnw - only meanful during wait
88 lvd 622
        begin
623
                if( port_wr )
624
                        wait_rnw <= 1'b0;
625
 
626
                if( port_rd )
627
                        wait_rnw <= 1'b1;
628
        end
629
 
630
 
631
 
632
 
633
 
4 lvd 634
        // VG93 control
200 lvd 635
        assign vg_cs_n =  (~shadow) | iorq_n | (rd_n & wr_n) | ( ~((loa==VGCOM)|(loa==VGTRK)|(loa==VGSEC)|(loa==VGDAT)) );
4 lvd 636
 
637
 
638
 
40 lvd 639
 
4 lvd 640
 
641
// reset rom selection
642
 
200 lvd 643
        always @(posedge zclk)
4 lvd 644
        begin
645
                rstsync1<=~rst_n;
646
                rstsync2<=rstsync1;
647
        end
648
 
649
 
650
 
651
 
652
// SD card (z-control¸r compatible)
653
 
654
        wire sdcfg_wr,sddat_wr,sddat_rd;
655
 
228 lvd 656
        assign sdcfg_wr = ( (loa==SDCFG) && port_wr && (!shadow) )                  ||
657
                          ( (loa==SDDAT) && port_wr &&   shadow  && (a[15]==1'b1) ) ;
4 lvd 658
 
228 lvd 659
        assign sddat_wr = ( (loa==SDDAT) && port_wr && (!shadow) )                  ||
660
                          ( (loa==SDDAT) && port_wr &&   shadow  && (a[15]==1'b0) ) ;
661
 
662
        assign sddat_rd = ( (loa==SDDAT) && port_rd              );
663
 
4 lvd 664
        // SDCFG write - sdcs_n control
200 lvd 665
        always @(posedge zclk, negedge rst_n)
4 lvd 666
        begin
667
                if( !rst_n )
668
                        sdcs_n <= 1'b1;
200 lvd 669
                else // posedge zclk
4 lvd 670
                        if( sdcfg_wr )
671
                                sdcs_n <= din[1];
672
        end
673
 
674
 
675
        // start signal for SPI module with resyncing to fclk
676
 
677
        reg sd_start_toggle;
678
        reg [2:0] sd_stgl;
679
 
680
        // Z80 clock
200 lvd 681
        always @(posedge zclk)
4 lvd 682
                if( sddat_wr || sddat_rd )
683
                        sd_start_toggle <= ~sd_start_toggle;
684
 
685
        // FPGA clock
686
        always @(posedge fclk)
687
                sd_stgl[2:0] <= { sd_stgl[1:0], sd_start_toggle };
688
 
689
        assign sd_start = ( sd_stgl[1] != sd_stgl[2] );
690
 
691
 
692
        // data for SPI module
693
        assign sd_datain = wr_n ? 8'hFF : din;
694
 
695
 
696
 
200 lvd 697
 
698
 
699
 
700
 
701
/////////////////////////////////////////////////////////////////////////////////////////////////
702
 
703
        ///////////////
704
        // ATM ports //
705
        ///////////////
706
 
707
        wire atm77_wr_fclk;
708
        wire zxevbf_wr_fclk;
709
 
270 lvd 710
        assign atmF7_wr_fclk = ( (loa==ATMF7) && (a[8]==1'b1) && shadow && port_wr_fclk ); // xFF7 and x7F7 ports, NOT xEF7!
200 lvd 711
        assign atm77_wr_fclk = ( (loa==ATM77) && shadow && port_wr_fclk );
712
 
713
        assign zxevbf_wr_fclk = ( (loa==ZXEVBF) && port_wr_fclk );
714
 
715
 
716
        // port BF write
717
        //
718
        always @(posedge fclk, negedge rst_n)
719
        if( !rst_n )
720
        begin
721
                shadow_en_reg = 1'b0;
722
                romrw_en_reg  = 1'b0;
723
        end
724
        else if( zxevbf_wr_fclk )
725
        begin
726
                shadow_en_reg <= din[0];
727
                romrw_en_reg  <= din[1];
728
        end
729
 
730
        assign romrw_en = romrw_en_reg;
731
 
732
 
733
 
734
        // port xx77 write
735
        always @(posedge fclk, negedge rst_n)
736
        if( !rst_n )
737
        begin
738
                atm_scr_mode = 3'b011;
739
                atm_turbo    = 1'b1;
262 lvd 740
 
270 lvd 741
                atm_pen =   1'b1; // no manager,
742
                atm_cpm_n = 1'b0; // permanent dosen (shadow ports on)
262 lvd 743
 
744
 
200 lvd 745
                atm_pen2     = 1'b0;
746
        end
747
        else if( atm77_wr_fclk )
748
        begin
749
                atm_scr_mode <= din[2:0];
750
                atm_turbo    <= din[3];
751
                atm_pen      <= ~a[8];
752
                atm_cpm_n    <=  a[9];
753
                atm_pen2     <= ~a[14];
754
        end
755
 
756
 
757
 
4 lvd 758
endmodule
200 lvd 759