%-------------------------------------------------------------------------- CompactFlash/IDE Interface for the Apple II computer Project Home: http://dreher.net/CFforAppleII/ Project Version 2.0 Nov 10, 2005 Version 2.0 - Added support for AT28C64 EEPROM and WP jumper 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, A5 : INPUT; % Note: A4 is missing, it didn't fit in device % A6, A7, A8, A9, A10 : INPUT; /RW, /DSEL, /IO_STRB, /IO_SEL, 7Mclk : INPUT; /EEPROM_WP : INPUT; /R_HOST, R_ATA, W_HOST, /W_ATA : OUTPUT; /IOWR, /IORD, /CS0, /CS1 : OUTPUT; /DBUS245, /EEPROM_CE : OUTPUT; LA0, LA1, LA2 : OUTPUT; /EEPROM_OE, /EEPROM_WE : OUTPUT; /C800_FF : OUTPUT; ) VARIABLE RESET_MASK, SET_MASK, /CFFF : NODE; DelayDSEL1, DelayDSEL2, NOT_7Mclk, LA3 : NODE; /EEAddr, CS_MASK : 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(!/CFFF, !/IO_SEL, 7Mclk, VCC, VCC); % EEPROM Address. Active low signal % /EEAddr = (/C800_FF # /IO_STRB) !$ /IO_SEL; % EEPROM Chip Enable % /EEPROM_CE = (/EEAddr # !/EEPROM_WP) & (/EEAddr # !/RW); % EEPROM Output Enable % /EEPROM_OE = !/RW # /EEAddr; % EEPROM Write Enable % /EEPROM_WE = /RW # !/EEPROM_WP # /EEAddr; %------------------------------------------------------------------------------% % 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 $CFFF and $CFEF for deselecting the onboard EPROM % /CFFF = !(A0 & A1 & A2 & A3 & A5 & A6 & A7 & 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 & /EEPROM_CE & /IO_SEL; END;