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