Name jride_isa; Assembly 0004; Revision P1 1.0; PartNo U1 ATF1508AS; Device f1508plcc84; Company Retrotronics.org; Designer Alan H.; Location None; Date October 2011; property ATMEL { xor_synthesis=on }; property ATMEL { logic_doubling=on }; property ATMEL { jtag=off }; PROPERTY ATMEL { preassign keep }; /* * Pin assignments * * Make all data and address outputs fast slew and all chip selects slow */ Pin 1 = RESET; Pin 4 = !IDE_RESET; Pin 35 = A0; Pin 36 = A1; Pin 40 = A2; Pin 39 = A3; Pin 41 = A4; Pin 44 = A5; Pin 45 = A6; Pin 46 = A7; Pin 51 = A8; Pin 55 = A9; Pin 52 = A10; Pin 54 = A11; Pin 61 = A12; Pin 60 = A13; Pin 63 = A14; Pin 62 = A15; Pin 65 = A16; Pin 64 = A17; Pin 67 = A18; Pin 69 = A19; Pin 70 = D0; Pin 73 = D1; Pin 74 = D2; Pin 76 = D3; Pin 75 = D4; Pin 77 = D5; Pin 80 = D6; Pin 79 = D7; Pin 23 = IDE_D0; Pin 20 = IDE_D1; Pin 18 = IDE_D2; Pin 17 = IDE_D3; Pin 12 = IDE_D4; Pin 11 = IDE_D5; Pin 8 = IDE_D6; Pin 5 = IDE_D7; Pin 6 = IDE_D8; Pin 9 = IDE_D9; Pin 10 = IDE_D10; Pin 15 = IDE_D11; Pin 14 = IDE_D12; Pin 16 = IDE_D13; Pin 21 = IDE_D14; Pin 22 = IDE_D15; Pin 28 = IDE_A0; Pin 27 = IDE_A1; Pin 29 = IDE_A2; Pin 25 = !IDE_RD; Pin 24 = !IDE_WR; Pin 71 = !MEMWR; Pin 68 = !MEMRD; Pin 37 = !ROM_CE; Pin 34 = !ROM_OE; Pin 58 = !ROM_WE; Pin 2 = !DIP1; Pin 84 = !DIP2; Pin 83 = !DIP3; Pin 81 = !DIP4; Pin 30 = !IDE_CE0; Pin 31 = !IDE_CE1; Pin 33 = ROM_A13; Pin 57 = ROM_A14; Pin 48 = ROM_A15; Pin 49 = ROM_A16; Pin 56 = ROM_A17; Pin 50 = ROM_A18; /* * Register field map for internal write only registers * accessed immedaitely after the IDE register window * used to control the ROM disk remap window address, * target page, and to allow independent reset of the * attached IDE disk. * * Select 0 Bit 0 reg0 ROM remap window A13 reference * 0 1 reg1 ROM remap window A14 reference * 0 2 reg2 ROM remap window A15 reference * 0 3 reg3 ROM remap window A16 reference * 0 4 ---- Reserved * 0 5 ---- Reserved * 0 6 ---- Reserved * 0 7 reg4 IDE reset control (1 = reset) * * Select 1 Bit 0 reg5 ROM remap target page bit 0 (A13) * 1 1 reg6 ROM remap target page bit 1 (A14) * 1 2 reg7 ROM remap target page bit 2 (A15) * 1 3 reg8 ROM remap target page bit 3 (A16) * 1 4 reg9 ROM remap target page bit 4 (A17) * 1 5 reg10 ROM remap target page bit 5 (A18) * 1 6 ---- Reserved * 1 7 reg11 ROM remap window enable/disable */ Pinnode = [reg11..0]; /* Register mapping aliases */ IDE_RESET = reg4; ROM_A18 = reg10; ROM_A17 = reg9; ROM_A16 = reg8; ROM_A15 = reg7; ROM_A14 = reg6; ROM_A13 = reg5; MAP16 = reg3; MAP15 = reg2; MAP14 = reg1; MAP13 = reg0; MAPE = reg11; /* * 16KB option ROM decode window at 16KB steps between * C0000 & E0000 matched against DIP switches 1-3 */ Pinnode = OPTION_WIN; OPTION_WIN = A19 & A18 & !A17 & !(A16 $ DIP1) & !(A15 $ DIP2) & !(A14 $ DIP3) & DIP4; /* * Break down of the 16KB option ROM decode window. * 14.5KB of ROM space, a virtualize 512 byte IDE sector * access buffer, 16 IDE device registers, and two * internal registers with-in this space. The 1006 * trailing addresses are unused. */ Pinnode = ROM_AREA; Pinnode = IDE_DATA; Pinnode = IDE_WIN; Pinnode = REG_CS0; Pinnode = REG_CS1; Pinnode = NP_IDE_DATA; field SUBADDR = [A13..0]; ROM_AREA = OPTION_WIN & SUBADDR:[0000..39FF]; IDE_DATA = OPTION_WIN & SUBADDR:[3A00..3BFF]; IDE_WIN = OPTION_WIN & SUBADDR:[3C00..3C0F]; REG_CS0 = OPTION_WIN & SUBADDR:[3C10..3C10]; REG_CS1 = OPTION_WIN & SUBADDR:[3C11..3C11]; NP_IDE_DATA = SUBADDR:[3A00..3BFF]; /* * 8KB flash disk remap window positioned at 8KB steps * between C0000 & E0000 matched against address in remap * register and remap enable control (bit 0) */ Pinnode = REMAP_WIN; REMAP_WIN = A19 & A18 & !A17 & !(A16 $ MAP16) & !(A15 $ MAP15) & !(A14 $ MAP14) & !(A13 $ MAP13) & MAPE; /* Flash/ROM chip select output signal */ ROM_CE = (MEMRD # MEMWR) & (ROM_AREA # REMAP_WIN); /* These lines are simply buffered through */ IDE_RD = MEMRD; IDE_WR = MEMWR; ROM_OE = MEMRD; ROM_WR = MEMWR; IDE_A0 = A0; IDE_A1 = A1; IDE_A2 = A2; /* * IDE strobe selection logic. These should be left * at slow slew while data and address lines fast to * (hopefully) prevent gate racing. I haven't yet * computed all the propagation times (by hand - FU Atmel) */ IDE_DATA_SEL = NP_IDE_DATA & ((!A0 & MEMRD) # (A0 & MEMWR)); IDE_CE0 = OPTION_WIN & (SUBADDR:[3C00..3C07] # IDE_DATA_SEL); IDE_CE1 = OPTION_WIN & SUBADDR:[3C08..3C0F]; /* Internal register loads */ reg11.d = D7; reg10.d = D5; reg9.d = D4; reg8.d = D3; reg7.d = D2; reg6.d = D1; reg5.d = D0; [reg11..5].ar = RESET; [reg11..5].ck = MEMWR & REG_CS1; reg4.d = D7; reg3.d = D3; reg2.d = D2; reg1.d = D1; reg0.d = D0; [reg4..0].ar = RESET; [reg4..0].ck = MEMWR & REG_CS0; /* * Bus steering and latch logic for 16-bit IDE data window * reads and writes. A single 8-bit latch is used to for * both directions. You could use two latches here, one * for read and one for write, but so far synthesis has * shown no combinatorial logic savings. * A rep movsw is used to transfer a sector. The 8088/V20 * will break each 16-bit mov into two successive 8-bit * bus cycles. When transfering a sector in from the drive, * the CS is asserted on the even address location and the * upper IDE byte is caught by the latch and returned during * the odd cycle. When transfering a sector out to the drive, * the CS is asserted on the odd address location presenting * the IDE lower byte latched in during the even cycle and * the IDE upper byte from the odd cycle ISA bus value. * * The switch power savings that could be gained by limiting * latching to only the IDE sector window is not worth the * combinatorial logic expense. */ Pinnode = [DR7..0]; DR7.d = IDE_D15; DR6.d = IDE_D14; DR5.d = IDE_D13; DR4.d = IDE_D12; DR3.d = IDE_D11; DR2.d = IDE_D10; DR1.d = IDE_D9; DR0.d = IDE_D8; [DR7..0].ar = RESET; [DR7..0].ck = !MEMRD # !IDE_DATA # A0; Pinnode = [DW7..0]; DW7.d = D7; DW6.d = D6; DW5.d = D5; DW4.d = D4; DW3.d = D3; DW2.d = D2; DW1.d = D1; DW0.d = D0; [DW7..0].ar = RESET; [DW7..0].ck = MEMWR & IDE_DATA & !A0; /* * 16-bit steering logic is only ever invoked for the * virtual IDE sector window selected below. In such * cases, the ISA bus will be presenting the upper byte * and the lower byte will come from the latch value * loaded during the previous even address write cycle. * * For normal 8-bit writes, the lower byte of the * buffered bus is a straight pass-through of the ISA * bus data lines. */ IDE_D15 = D7; IDE_D14 = D6; IDE_D13 = D5; IDE_D12 = D4; IDE_D11 = D3; IDE_D10 = D2; IDE_D9 = D1; IDE_D8 = D0; IDE_D7 = (A9 & DW7) # (!A9 & D7); IDE_D6 = (A9 & DW6) # (!A9 & D6); IDE_D5 = (A9 & DW5) # (!A9 & D5); IDE_D4 = (A9 & DW4) # (!A9 & D4); IDE_D3 = (A9 & DW3) # (!A9 & D3); IDE_D2 = (A9 & DW2) # (!A9 & D2); IDE_D1 = (A9 & DW1) # (!A9 & D1); IDE_D0 = (A9 & DW0) # (!A9 & D0); [IDE_D15..0].oe = MEMWR; /* * The only thing on the buffered data bus is the IDE * connector. Enable output on reads for both IDE * access windows (sector & register). * * Bus steering is based on: * * - Sector window even read: IDE lower -> ISA (latches upper) * - Sector window odd read: Latched IDE upper -> ISA * - Register access window: IDE lower -> ISA (pass-through) */ READ_LATCH = A9 & A0; D0 = (READ_LATCH & DR0) # (!READ_LATCH & IDE_D0); D1 = (READ_LATCH & DR1) # (!READ_LATCH & IDE_D1); D2 = (READ_LATCH & DR2) # (!READ_LATCH & IDE_D2); D3 = (READ_LATCH & DR3) # (!READ_LATCH & IDE_D3); D4 = (READ_LATCH & DR4) # (!READ_LATCH & IDE_D4); D5 = (READ_LATCH & DR5) # (!READ_LATCH & IDE_D5); D6 = (READ_LATCH & DR6) # (!READ_LATCH & IDE_D6); D7 = (READ_LATCH & DR7) # (!READ_LATCH & IDE_D7); [D7..0].oe = MEMRD & OPTION_WIN & SUBADDR:[3A00..3C0F];