Name PDP_MAIN2; Assembly 0001; Revision 2.7; PartNo U25 ATF1508AS; Device f1508ispplcc84; Company S100Computers.com; Designer John Monahan; Location San Ramon, CA; Date 5/8/2018; property ATMEL { xor_synthesis=on }; property ATMEL { logic_doubling=on }; property ATMEL { jtag=on }; PROPERTY ATMEL { preassign keep }; PROPERTY ATMEL { TMS_pullup=on }; PROPERTY ATMEL { TDI_pullup=on }; /* ------ BOARD CPLD IS SETUP TO RUN AS A S100 BUS >>>> SLAVE <<<<< PDP11 Board(V2.5f), U25 ---- * Pin assignments * Make all data and address outputs fast slew and all chip selects slow * Note this version allows for 16 & 8 bit RAM and Ports access. * * * V1.3 10/6/2017 ;Added interrupt processing * V2.4 10/12/2017 ;Add connection with CPU board UART * V2.41 11/06/2017 ;All 4 UART Interrupts working * V2.5f 12/3/2017 ;Modified for the extra functions incoporated in this second CPLD * V2.7 12/11/2017 ;Added timer circuit to CPU board * V2.72 1/22/2018 ;Added ELM timer circuit to CPU board * V2.72A 5/8/2018 ;Added code to detect invalid IO Ports * */ Pin 83 = CPLD_CLK_IN; /* 20 MHz (UART_CLK)*/ Pin 2 = ALE; /* Used by power up jump */ Pin 81 = HZ60; /* 60Hz Clock for timer */ Pin 4 = DAL0; Pin 5 = DAL1; Pin 6 = DAL2; Pin 8 = DAL3; Pin 9 = DAL4; Pin 10 = DAL5; Pin 11 = DAL6; Pin 15 = DAL7; Pin 16 = LAIO0; Pin 17 = LAIO1; Pin 18 = LAIO2; Pin 20 = LAIO3; Pin 21 = TIMER_ACK; /* To Overhead connector and CPU pin 9 */ Pin 22 = POWER_UP; /* Pulse U1 & U35 on power up */ Pin 24 = VALID_PORT; Pin 25 = ROM_PAGE; Pin 27 = pDBIN; /* Input, Buffered S100 bus pDBIN pin */ Pin 28 = sINP; /* Input, Buffered S100 bus sINP pin */ Pin 29 = BUFCTL; Pin 30 = S0; Pin 31 = S1; /* From Support board interrupt circuit */ Pin 33 = S2; Pin 34 = VEC_DAL0; Pin 35 = VEC_DAL1; Pin 36 = VEC_DAL2; /* To place interrupt vector on bus after INTA */ Pin 37 = VEC_DAL3; Pin 39 = VEC_DAL4; Pin 40 = VEC_DAL5; Pin 41 = VEC_DAL6; Pin 44 = VEC_DAL7; Pin 46 = SB_ACTIVE; /* LOW if the PDP11 Support Board is active. */ Pin 48 = VEC_OE; Pin 49 = ROM_ADDRESS; Pin 50 = UART_ADDRESS; Pin 51 = DO_BIT6; /* S100 Bus Data Out line bit 6 */ Pin 52 = TMAXPU; /* Critical signal, must be high for this CPU board to be active on the S100 bus as a temporary master */ Pin 54 = S100_LA15_13; /* Note all the Address lines below are buffered */ Pin 55 = LA21_19; Pin 57 = STATUS_READ_BIT7; Pin 56 = STATUS_READ_BIT6; Pin 58 = LA18_16; Pin 60 = LA15; Pin 61 = LA14; Pin 63 = LA13; Pin 64 = LA12; Pin 65 = LA11; Pin 67 = LA10; Pin 68 = LA9; Pin 69 = LA8; Pin 70 = LA7; Pin 73 = LA6; Pin 74 = LA5; Pin 75 = LA4; Pin 76 = LA3; Pin 77 = LA2; Pin 79 = LA1; Pin 80 = LA0; Pin 84 = sOUT; Pin 1 = MASTER_RESET; /* S100 Bus reset. Active LOW */ Pin 12 = TIMER_STATUS_READ; /* Read Timer Status Buffer enable */ Pin 45 = TIMER_EVENT; /* Timer Event sent to pin 8 of CPU */ Pinnode = [CD6..0]; Pinnode = SLOW_CLOCK; CD0.t = 'b'1; /* 10MHz */ CD1.t = CD0; /* 5 MHz */ CD2.t = CD0 & CD1; /* 2.5 MHz */ CD3.t = CD0 & CD1 & CD2; /* 1.25 Mhz */ CD4.t = CD0 & CD1 & CD2 & CD3; /* 625 KHz */ CD5.t = CD0 & CD1 & CD2 & CD3 & CD4; /* 312 KHz */ CD6.t = CD0 & CD1 & CD2 & CD3 & CD4 & CD5; /* 156 KHz */ [CD6..0].ckmux = CPLD_CLK_IN; SLOW_CLK = CD6; /* 156.24/16 KHz used for pulse delays below */ Pinnode = reg0; /* >>>>> Power Up, jump to RAM location circuit <<<< */ !reg0.d = !DAL0 & !DAL1 & !DAL2 & !DAL3 & !DAL4 & !DAL5 & !DAL6 & !DAL7 # !DAL0 & DAL1 & !DAL2 & !DAL3 & !DAL4 & !DAL5 & !DAL6 & !DAL7; reg0.ar = !MASTER_RESET; reg0.ck = ALE; !POWER_UP = !reg0 & LAIO3 & LAIO2 & LAIO1 & !LAIO0 & !BUFCTL; /*-------------------------------------------------------------------------------------------------------------------------------------------*/ /* >>>>>>>>> SELECT ONBOARD UART <<<<<<<<<< */ !UART_ADDRESS = ((LA21_19 & LA18_16 /* Always 3F */ & LA15 & LA14 & LA13 & LA12 & LA11 & LA10 & LA9 & LA8 /* Note address lines before U29 (FFxx) */ & !LA7 & !LA6 & !LA5 & LA4 & !LA3 & SB_ACTIVE) /* All 4 U6 ODT UART Ports, 1F10 to 1F17 do NOT go to the S100 bus */ /* The ODT UART is on the Support Board. This is an extra UART */ # (LA21_19 & LA18_16 /* Always 3F */ & LA15 & LA14 & LA13 & LA12 & LA11 & LA10 & LA9 & LA8 /* Note address lines before U29 (FFxx) */ & !LA7 & LA6 & LA5 & LA4 & !LA3 & !SB_ACTIVE)); /* All 4 U6 ODT UART Ports, 1F70 to 17F7 do NOT go to the S100 bus */ /* The ODT UART is on this Board */ Pinnode = PROPELLER_PORTS; Pinnode = IOBYTE_PORT; Pinnode = ODT_CONSOLE_PORTS; Pinnode = DEBUG_CONSOLE_PORTS; Pinnode = TU58_PORTS; Pinnode = TIMER_PORTS; Pinnode = SERIAL_BOARD_PORTS; /* S100Computers Serial board speaker, B CTL port (Zilog SCC Chip) */ Pinnode = PRINTER1_PORTS; /* ST8C4 Printer Control Port */ Pinnode = PRINTER2_PORTS; /* LP11 Printer data port */ Pinnode = ROM_PAGE_PORTS; /* Port to shadow in ROM High/low Pages */ Pinnode = UNDEF_PORTS; /* For debugging */ FIELD IOADDR = [LA12..0]; !PROPELLER_PORTS = IOADDR:['h'0000..0001]; !IOBYTE_PORT = IOADDR:['h'00EE..00EF]; !ODT_CONSOLE_PORTS = IOADDR:['h'1F70..1F77]; !DEBUG_CONSOLE_PORTS = IOADDR:['h'1F10..1F17]; !TU58_PORTS = IOADDR:['h'1F40..1F47]; !TIMER_PORTS = IOADDR:['h'1F66..1F67]; !SERIAL_BOARD_PORTS = IOADDR:['h'00A0..00A3]; !PRINTER1_PORTS = IOADDR:['h'00C0..00C3]; !PRINTER2_PORTS = IOADDR:['h'1F4C..1F4F]; !ROM_PAGE_PORTS = IOADDR:['h'00E4..00E5]; !UNDEF_PORTS = IOADDR:['h'009C..009D]; VALID_PORT = ( !UNDEF_PORTS # !UART_ADDRESS # !ODT_CONSOLE_PORTS # !TU58_PORTS # !DEBUG_CONSOLE_PORTS # !IOBYTE_PORT # !TIMER_PORTS # !SERIAL_BOARD_PORTS # !PRINTER1_PORTS # !PRINTER2_PORTS # !ROM_PAGE_PORTS # !PROPELLER_PORTS); /*-------------------------------------------------------------------------------------------------------------------------------------------*/ /* >>>> ACTIVATE ONBOARD TMAx PORT -- EDH <<<<<<<<<< */ Pinnode = PULSE_TMA_L; /* >>>> DE-ACTIVATE ONBOARD TMAx PORT -- E3H <<<<<<<<<< */ Pinnode = PULSE_TMA_H; Pinnode = reg1; /* >>>>> ACTIVATE ONBOARD TMAx S100 bus 8 bit PORT -- 00EDH <<< */ !PULSE_TMA_H = (LA0 & !LA1 & LA2 & LA3 & !LA4 & LA5 & LA6 & LA7 & !LA8 & !LA9 & !LA10 & !LA11 & !LA12 & !S100_LA15_13 /* Note LA13 - LA15 invalid on Z80 side of bus */ & sINP & pDBIN); reg1.d = 'b'0; reg1.ck = !PULSE_TMA_H; reg1.ap = !MASTER_RESET # !PULSE_TMA_L; !TMAXPU = reg1; /* Will go HIGH to activate this Slave board, (but LOW to P10 via U19F) */ !PULSE_TMA_L = (LA0 & LA1 & !LA2 & !LA3 & !LA4 & LA5 & LA6 & LA7 & !LA8 & !LA9 & !LA10 & !LA11 & !LA12 & LA13 & LA14 & LA15 /* Will reset TMAXPU back LOW by output to PORT -- E0E3H*/ & sINP & pDBIN); /* Note this only works with P10 jumpered 1-2 */ /*-------------------------------------------------------------------------------------------------------------------------------------------*/ Pinnode = PULSE_PAGE_L; /* >>>> SET ROM ADDRESS LINE DAL13 HIGH -- E0E4H <<<<<<<<<< */ Pinnode = PULSE_PAGE_H; /* >>>> SET ROM ADDRESS LINE DAL 3 LOW -- E0E5H <<<<<<<<<< */ Pinnode = reg6; /* Code to page ROM in the PDP address space via Port E0E4H */ !PULSE_PAGE_H = (!LA0 & !LA1 & LA2 & !LA3 & !LA4 & LA5 & LA6 & LA7 /* E4 */ & !LA8 & !LA9 & !LA10 & !LA11 & !LA12 & LA13 & LA14 & LA15 /* E0 (of E0E4H for HIGH Page) */ & sINP & pDBIN); reg6.d = 'b'0; reg6.ck = !PULSE_PAGE_H; reg6.ap = !MASTER_RESET # !PULSE_PAGE_L; !ROM_PAGE = reg6; /* DAL13 HIGH for ROM. Activate upper half of 28C64*/ /* Code to shadow back IN ROM in the PDP address space via Port E0E5H */ !PULSE_PAGE_L = (LA0 & !LA1 & LA2 & !LA3 & !LA4 & LA5 & LA6 & LA7 /* E5 */ & !LA8 & !LA9 & !LA10 & !LA11 & !LA12 & LA13 & LA14 & LA15 /* E0(of E0E5H for LOW Page) */ & sINP & pDBIN); /*-------------------------------------------------------------------------------------------------------------------------------------------*/ Pinnode = PULSE_ROM_L; /* >>>>> SHADOW OUT ONBOARD ROM PORT -- E1H <<<<<<<<<< */ Pinnode = PULSE_ROM_H; /* >>>>> SHADOW IN ONBOARD ROM PORT -- E2H <<<<<<<<<< */ Pinnode = reg2; Pinnode = SHADOW_ROM; /* Code to shadow out ROM in the PDP address space via Port E1H */ /* Pulse Pin 18 (Will toggle in/out ROM in CPLD code) */ !PULSE_ROM_H = (LA0 & !LA1 & !LA2 & !LA3 & !LA4 & LA5 & LA6 & LA7 /* E1 */ & !LA8 & !LA9 & !LA10 & !LA11 & !LA12 & LA13 & LA14 & LA15 /* E0 (of E0E1H for shadow OUT) */ & sINP & pDBIN); reg2.d = 'b'0; reg2.ck = !PULSE_ROM_H; reg2.ap = !MASTER_RESET # !PULSE_ROM_L; /* To switch back in ROM */ !SHADOW_ROM = reg2; /* Will go HIGH to shadow out the ROM */ /* Code to shadow back IN ROM in the PDP address space via Port E2H */ !PULSE_ROM_L = (!LA0 & LA1 & !LA2 & !LA3 & !LA4 & LA5 & LA6 & LA7 /* E2 */ & !LA8 & !LA9 & !LA10 & !LA11 & !LA12 & !S100_LA15_13 /* E0 (of E0E2H for shadow IN) */ & sINP & pDBIN); /* >>>>>>>>> SELECT ONBOARD ROM <<<<<<<<<< */ !ROM_ADDRESS = LA15 & LA14 & !LA13 & !sOUT & !sINP & !SHADOW_ROM; /* RAM (only) C000-DFFF */ /*-------------------------------------------------------------------------------------------------------------------------------------------*/ /* >>>>>>>>>>>>>>>>> Interrupt vectors <<<<<<<<<<<<<<<< */ FIELD INT_VEC = [VEC_DAL7,VEC_DAL6,VEC_DAL5,VEC_DAL4,VEC_DAL3,VEC_DAL2,VEC_DAL1,VEC_DAL0]; FIELD INT_CODE = [S2,S1,S0]; !VEC_OE = LAIO3 & LAIO2 & !LAIO1 & LAIO0 & !BUFCTL; /* Instruction INTA vector (1101) WRITE RAM adddress on DAL address lines */ /* This signal activeates U39 & U40 placing the INT_CODE bbelow on the /* CPU DAL lines. The value is a RAM location between 0H & 100H */ TABLE INT_CODE => INT_VEC { 'b'000 => 'h'30; 'b'001 => 'h'38; 'b'010 => 'h'34; /* Data order... U20 pin 7,8,9 = S0,S1,S2 */ 'b'011 => 'h'3C; 'b'100 => 'h'78; 'b'101 => 'h'78; 'b'110 => 'h'78; 'b'111 => 'h'80; } /*-------------------------------------------------------------------------------------------------------------------------------------------*/ /* >>>>>>>>>>>>>>>>>>>> TIMER <<<<<<<<<<<<<<<<<<<< */ Pinnode = reg7,reg8; Pinnode = TIMER_ENABLE; Pinnode = TIMER_STATUS_BUFFER; /* Note TIMER_STATUS_BUFFER is local to this CPLD. */ !TIMER_ACK = !LAIO3 & LAIO2 & !LAIO1 & LAIO0 & !DAL7 & DAL6 & !DAL5 & !DAL4 & !DAL3 & !DAL2 & !DAL1 & !DAL0; !TIMER_STATUS_BUFFER = LA21_19 & LA18_16 /* Always 3F */ & LA15 & LA14 & LA13 & LA12 & LA11 & LA10 & LA9 & LA8 /* Note address lines before U29 (FF66) */ & !LA7 & LA6 & LA5 & !LA4 & !LA3 & LA2 & LA1 & !LA0; /* Ports 1F66 */ TIMER_STATUS_WRITE = !TIMER_STATUS_BUFFER & sOUT; /* Byte Write FF66H = 1F66H (Even Address. Local here no need for !bpWR) */ !TIMER_STATUS_READ = !TIMER_STATUS_BUFFER & sINP & pDBIN; /* Byte/Word Read FF66H = 1F66H & 1F67H */ !STATUS_READ_BIT7 = !TIMER_EVENT; /* Bit 7 of Low Byte for Timer Status Port (0=Interrupt) */ !STATUS_READ_BIT6 = TIMER_ENABLE; /* Bit 6 of Low Timer Status Port (0=Timer Active) */ reg7.d = DO_BIT6; reg7.ck = TIMER_STATUS_WRITE; reg7.ar = !MASTER_RESET; TIMER_ENABLE = reg7; reg8.d = 'b'1; reg8.ck = TIMER_ENABLE & HZ60; reg8.ar = !MASTER_RESET # !TIMER_ACK; /* Clear Interrupt when EVENT_ACK is returned from CPU Board, (or reset, U9A) */ !TIMER_EVENT = reg8 & TIMER_ENABLE & HZ60; /* Sent interrupt to S100 bus via U19A */