%-------------------------------------------------------------------------- CompactFlash/IDE Interface for the Apple II computer Project Home: http://dreher.net/CFforAppleII/ Project Version 1.4 April 23, 2005 Version 1.4 - Fix timing problem introduced in V1.3: /IORD was being being de-asserted before the falling edge of 6502's PH2 - Latch A3-A0 to insure that address is stable through entire ATA cycle. - Add outputs for latched A2 thru A0 signals. This supports a hardware change that allows many more CF cards to work with the CFFA card. - Remove use of nandltch and replace with SRFF. This is now synchronous logic. - Adjust W_HOST timing slightly - Adjust /W_ATA timing so it only asserts when needed - Adjust /R_ATA timing so it only asserts when needed - Remove one delay FF on /DSEL, it was not needed Version 1.3 - Greatly improved timing margins on ATA signals: /IORD, /IOWR, /CS0, /CS1, by adding two additional D-FF and inverting 7M Clk. - Now works with Apple ][+ bus timing. Version 1.2 - Two or more cards would not work in system at same time because the DBUS245 select logic did not take into account expansion ROM enable flipflop state. - Moved all logic into appleidelogic.tdf file. Version 1.1 - Add 7M clk & DFF to fix IDE drives /IORD & /IOWR timing Version 1.0 - Initial Release Note: Remember that the Apple II Bus does not have Phase 2! -------------------------------------------------------------------------------% FUNCTION DFF (D, CLK, CLRN, PRN) RETURNS (Q); FUNCTION DFFE (D, CLK, CLRN, PRN, ENA) RETURNS (Q); FUNCTION SRFF (S, R, CLK, CLRN, PRN) RETURNS (Q); SUBDESIGN AppleIDELogic ( A0, A1, A2, A3, A8, A9, A10 : INPUT; /RW, /DSEL, /IO_STRB, /IO_SEL, 7Mclk : INPUT; /R_HOST, R_ATA, W_HOST, /W_ATA : OUTPUT; /IOWR, /IORD, /CS0, /CS1 : OUTPUT; /DBUS245, /EPROM_EN, NOT_RW : OUTPUT; CS_MASK, LA0, LA1, LA2 : OUTPUT; ) VARIABLE SET_MASK, RESET_MASK, /CFXX, /C800_FF : NODE; DelayDSEL1, DelayDSEL2, NOT_7Mclk, LA3 : NODE; BEGIN DEFAULTS CS_MASK = GND; /C800_FF = VCC; END DEFAULTS; % Create an inverted version of the 7Mhz clock % NOT_7Mclk = !7Mclk; LA0 = DFFE(A0, 7Mclk, VCC, VCC, /DSEL); LA1 = DFFE(A1, 7Mclk, VCC, VCC, /DSEL); LA2 = DFFE(A2, 7Mclk, VCC, VCC, /DSEL); LA3 = DFFE(A3, 7Mclk, VCC, VCC, /DSEL); % Expansion Slot ROM enable Flip-flop. Active low signal % /C800_FF = SRFF(!/CFXX, !/IO_SEL, 7Mclk, VCC, VCC); % Output for PCB Version 1.2 Revs A & B, chip U2 is wired such that the % % direction pin needs an inverted version of R/W % NOT_RW = !/RW; % EPROM select. Active low signal % /EPROM_EN = (/C800_FF # /IO_STRB) !$ /IO_SEL; %------------------------------------------------------------------------------% % Fix for SanDisk Family of CompactFlash drives. True IDEmode is not quite % % True! The idea here is to mask the read cycle that proceeds all write cycles % % because the read cycle was confusing the Sandisk % %------------------------------------------------------------------------------% SET_MASK = /DSEL # (LA3 # LA2 # LA1 # !LA0); RESET_MASK = /DSEL # (LA3 # LA2 # !LA1 # LA0); CS_MASK = SRFF(!SET_MASK, !RESET_MASK, 7Mclk, VCC, VCC); %------------------------------------------------------------------------------% % Device select is clocked through two D-FF to create a late falling edge % % and a early rising edge for /IORD and /IOWR. The address lines A0-A3 are used% % are used to inhibit /IORD and /IOWR signal generation on reads to onboard % % registers that don't map to the CF card, e.g. Latches % % the /IOWR signal is delayed one 7M clock longer that /IORD to allow for worst% % case data setup time of 200ns on 65C02 + 60ns setup time before IOWR is % % asserted on CF card % %------------------------------------------------------------------------------% DelayDSEL1 = DFF(/DSEL, NOT_7Mclk, VCC, VCC); DelayDSEL2 = DFF(DelayDSEL1, NOT_7Mclk, VCC, VCC); /IOWR = /DSEL # DelayDSEL2 # /RW # !(LA3 # LA2 # LA1 # LA0); /IORD = /DSEL # DelayDSEL1 # !/RW # !(LA3 # LA2 # LA1 # LA0); % Decode address range $CFxx for deselecting the onboard EPROM % /CFXX = !(A8 & A9 & A10 & !/IO_STRB); % Output Enable when reading High Byte Latch by host: $C0n0 % /R_HOST = /DSEL # LA3 # LA2 # LA1 # LA0 # !/RW; % Latch High byte of ATA device when reading $C0n8 % R_ATA = !/DSEL & !DelayDSEL1 & LA3 & !LA2 & !LA1 & !LA0 & /RW; % Latch data written to C0n0 by host(eg. Slot 7: $C0F0). This will become the % % high byte of the ATA data word when a write to C0n8 occures. % W_HOST = !/DSEL & !DelayDSEL1 & !(LA3 # LA2 # LA1 # LA0) & !/RW; % Output enable logic to drive the high of the ATA bus from U3 when a write % % to C0n8 occures % /W_ATA = DelayDSEL1 # !LA3 # LA2 # LA1 # LA0 # /RW; % Device chip select logic % /CS0 = (/DSEL & DelayDSEL1) # !LA3 # (CS_MASK & /RW); /CS1 = (/DSEL & DelayDSEL1) # (LA3 # !(LA1 & LA2)) # (CS_MASK & /RW); /DBUS245 = /DSEL & /EPROM_EN & /IO_SEL; END;