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 |