Name QBus11 ; PartNo 00 ; Date 10/11/2001 ; Revision 11 ; Designer CHD ; Company ; Assembly None ; Location ; Device f1508ispplcc84 ; /* PIO Mode Only Adapter */ $define NO_DMA /* PIO mode logic */ /* $define DMA */ /* DMA mode logic */ /* $define JUMPERS */ /* include logic for address switches */ /* if not defined, address is hardwired */ /* editor font: Courier New, Regular, 10 */ /* BB +--------------------------------+ | | +-----+ | +----------+ +-----+ QB | |<---+-+------| | CTL | | ----|TRANS| | | CPLD |---------| ATA | | | TSBUF | | | | +-----+ ^ | | +-----+ | | +----------+ +---------+ | BA | | +-----+ | QB | | | ----|TRANS|------------------+ | | +-----+ */ /* Device Selection */ /* Q22 addressing */ /* 1 7 7 6 0 0 0 0 */ /* 1 111 111 11A AAA AAA BBR RR0 */ /* where A is the variable base CSR address */ /* B is the register bank */ /* R is the register select */ /* 1 111 111 11A AAA AAA A00 000 CSR - base control register (including DMA address extension) */ /* 1 111 111 11A AAA AAA A00 010 CNT - DMA count register - NOT IMPLEMENTED (reserved) */ /* 1 111 111 11A AAA AAA A00 100 DMA - DMA address register - NOT IMPLEMENTED (reserved) */ /* 1 111 111 11A AAA AAA A00 110 VECT - interupt vector number */ /* 1 111 111 11A AAA AAA A01 000 (reserved) */ /* 1 111 111 11A AAA AAA A01 010 (reserved) */ /* 1 111 111 11A AAA AAA A01 100 CS1 disk controller register */ /* 1 111 111 11A AAA AAA A01 110 (reserved) */ /* 1 111 111 11A AAA AAA A1X XX0 CS0 disk controller registers */ /* clock rate: 32MHz * /* state1 state2 state3 state4 state5 */ /* minimum delay 1 2 3 4 5 */ /* 31ns 63ns 94ns 125ns 156ns */ /* maximum delay 2 3 4 5 6 */ /* 63ns 94ns 125ns 156ns 188ns */ $define TRUE 'b'1 $define FALSE 'b'0 /* DECLARATION */ /* Adapter Tri-State Bus */ pin [8, 9, 6, 5, 4, 37, 36, 35, 31, 30, 28, 29, 27, 11, 24, 10] = [DAB0..15]; field DAB = [DAB0..15]; /* Full word width bus */ field DAB_HIGH = [DAB8..DAB15]; /* Upper byte */ field DAB_LOW = [DAB0..DAB7]; /* Lower byte */ /* disk control signals */ pin [49, 48, 61] = [DA0..2]; /* disk register address */ pin 17 = !DCS1; /* disk chip select 0 - pin */ node CS1; /* disk chip select 0 latch */ pin 34 = !DCS0; /* disk chip select 1 - pin */ node CS0; /* disk chip select 1 latch */ pin 16 = !DIOR; /* disk controller read operation */ pin 15 = !DIOW; /* disk controller write operation */ pin 39 = DIORDY; /* disk controller ready for word transfer */ pin 40 = DINTRQ; /* disk controller interrupt request */ pin 50 = !DIOCS16; /* disk controller 16-bit transfer operation */ pin 60 = !DRESET; /* disk controller hardware reset */ /* QBUS control signals */ pin 1 = INIT; /* bus reset */ pin 58 = S7; /* device page select */ pin 81 = SYNC; /* bus address sync */ pin 2 = DIN; /* data read cycle */ pin 45 = DOUT; /* data write cycle */ pin 25 = RPLY; /* bus cycle handshake */ pin 18 = IRQ4O; /* interrupt request - level 4 - QBus out*/ pin 44 = IRQ5; /* interrupt request - level 5 */ pin 46 = IRQ6; /* interrupt request - level 6 */ pin 41 = IAKI; /* interrupt acknowledge daisy chain in */ pin 12 = IAKO; /* interrupt acknowledge daisy chain out */ $ifdef DMA pin = [BDAL16..21]; /* extended address bus */ $endif pin 83 = CLOCK32; /* clock for delays */ pin 20 = !QB_DREN; /* Qbus read - enable OC bus drivers */ pin 21 = !QB_TSEN; /* Qbus write - enable TS buffers between bus A and bus B */ pin = SEL; /* address match */ node [RPLYD0..3]; /* state vector for RPLY delay */ node [IOWD0..3]; /* state vector for IOW delay */ node INT_ARB_WON; /* internal signal indicating that adapter gets interrupt */ node ATA_IRQ; /* internal F/F to capture drive interrupt request */ $ifdef JUMPERS /* Option Configuration */ pin = [CSR_BASE0..7]; /* CSR base address jumpers */ field CSR_BASE = [CSR_BASE0..7]; field DAB_CSR = [DAB5..12]; $endif /* TEST and misc signals */ pin 22 = SYNC_LITE; /* light driver showing bus activity */ pin = ieck; /* CSR - Control and Status Register */ pin = CS_COM; /* internal select */ $ifdef DMA node [EXT_DMAADR0..5]; /* 15..10: DMA address extension */ $endif pin = INT_ENABLE; /* 6: interrupt enable from disk controller to QBus */ node IORDY_ENABLE; /* 5: use IORDY signal from disk controller */ $ifdef DMA /* DMACNT - DMA Word Tranfer Count Register */ pin = CS_DMACNT; /* internal select */ node [DMACNT0..7]; /* DMA word transfer count */ field DMACNT = [DMACNT0..7]; /* DMAADR - DMA Address Register */ pin = CS_DMAADR; /* internal select */ node [DMAADR0..15]; /* DMA buffer address */ field DMAADR = [DMAADR0..15]; $endif /* VECTOR - Interrupt Vector Number Register */ pin = CS_VECT; /* internal select */ node [VECTOR0..6]; /* Interrupt vector number */ field VECTOR = [VECTOR0..6]; field DAB_VECT = [DAB2..8]; /* reserved space */ node RSRVD; field REG_ADDR = [DAB0..4]; /* LOGIC */ /* QBUS Reset */ DRESET = INIT; /* QBUS Addressing */ /* 1 111 111 11A AAA AAA BBR RR0 */ /* 1 7 7 7 1 0 0 0 */ $ifndef JUMPERS SEL = S7 & DAB:'b'xxxxxxxxx10010000xxxxx; $endif $ifdef JUMPERS field MATCH = [MATCH0..7]; MATCH = !(CSR_BASE $ DAB_CSR); SEL = S7 & MATCH:&; $endif CS_COM.L = SEL & REG_ADDR:'b'00000; /* BASE + 0 */ CS_COM.LE = !SYNC; $ifdef DMA CS_DMACNT.L = SEL & REG_ADDR:'b'00010; /* BASE + 2 */ CS_DMACNT.LE = !SYNC; CS_DMAADR.L = SEL & REG_ADDR:'b'00100; /* BASE + 4 */ CS_DMAADR.LE = !SYNC; $endif CS_VECT.L = SEL & REG_ADDR:'b'00110; /* BASE + 6 */ CS_VECT.LE = !SYNC; RSRVD.L = SEL & REG_ADDR:'b'01000 /* BASE + 8 */ # SEL & REG_ADDR:'b'01010 /* BASE + 10 */ # SEL & REG_ADDR:'b'01110; /* BASE + 14 */ RSRVD.LE = !SYNC; $ifndef DMA append RSRVD.L = SEL & REG_ADDR:'b'00010 /* BASE + 2 */ # SEL & REG_ADDR:'b'00100; /* BASE + 4 */ $endif CS1.L = SEL & REG_ADDR:'b'01100; /* BASE + 12 */ CS1.LE = !SYNC; DCS1 = CS1 & SYNC; CS0.L = SEL & REG_ADDR:'b'1XXX0; /* BASE + 16 */ CS0.LE = !SYNC; DCS0 = CS0 & SYNC; [DA0..2].L = [DAB1..3]; /* save for disk register select */ [DA0..2].LE = !SYNC; DISK_SEL = CS0 # CS1; $ifdef DMA ADPTR_SEL = CS_COM # CS_VECT # CS_DMACNT # CS_DMAADR # RSRVD; $endif $ifndef DMA ADPTR_SEL = CS_COM # CS_VECT # RSRVD; $endif FAST_CYCLE = CS0 & [DA0..2]:'b'000; /* data register */ DIOCS16 = FAST_CYCLE; /* I/O Control - QBUS read */ IOR = DISK_SEL & DIN; /* disk controller read */ DIOR = IOR; /* pin */ QBR = (DISK_SEL # ADPTR_SEL) & DIN; /* enable QBUS drivers */ QB_DREN = QBR # IAKI & INT_ARB_WON; /* Reply */ /* Reply from DIN = 91ns for byte transfers */ /* = 30ns for word transfers */ append RPLY = DIN & ADPTR_SEL # DIN & !FAST_CYCLE & RPLYD3 & (IORDY_ENABLE & DIORDY # !IORDY_ENABLE) # DIN & FAST_CYCLE & RPLYD1 & (IORDY_ENABLE & DIORDY # !IORDY_ENABLE); /* I/O Control - QBUS write */ IOW = DISK_SEL & DOUT & SYNC & !IOWD3; /* disk controller write */ DIOW = IOW; /* pin */ QBW = (DISK_SEL # ADPTR_SEL) & DOUT; /* connect bus A to bus B */ QB_TSEN = QBW # !SYNC & !(IAKI & INT_ARB_WON); /* let the Qbus address pass thru */ /* Reply */ /* Reply from DOUT = 91ns for byte transfers */ /* = 30ns for word transfers */ append RPLY = DOUT & ADPTR_SEL # DOUT & IOWD1; RPLYD0.D = DISK_SEL & (DIN # DOUT); /* synchronizer */ RPLYD1.D = RPLYD0; /* 31ns */ RPLYD2.D = RPLYD0 & RPLYD1; /* 62ns */ RPLYD3.D = RPLYD0 & RPLYD2; /* 94ns */ [RPLYD0..3].CK = CLOCK32; IOWD0.D = DOUT /* synchonizer */ & (!FAST_CYCLE & RPLYD3 # FAST_CYCLE & RPLYD1) & (IORDY_ENABLE & DIORDY # !IORDY_ENABLE); IOWD1.D = IOWD0; /* 31ns 63ns 125ns */ IOWD2.D = IOWD0 & IOWD1; /* 63ns 94ns 156ns */ IOWD3.D = IOWD0 & IOWD2; /* 94ns 125ns 188ns */ [IOWD0..3].CK = CLOCK32; /* word byte */ append DAB = 'b'0000000000000000; append DAB.OE = ADPTR_SEL & DIN & SYNC; /* QBus Interrupt Cycle */ $ifdef notdefined ATA_IRQ.D = TRUE; ATA_IRQ.CK = INT_ENABLE & DINTRQ; /* interrupt is triggered on leading edge of DINTRQ */ ATA_IRQ.AR = INT_ARB_WON & IAKI; /* clear interrupt on acknowledge */ $endif ATA_IRQ = INT_ENABLE & DINTRQ; IRQ4O.L = ATA_IRQ; /* QBus signal to processor */ IRQ4O.LE = !DIN; /* Hold during arbitration period */ INT_ARB_WON.L = IRQ4O & !IRQ5 & !IRQ6; /* latch arbitration */ INT_ARB_WON.LE = !IAKI; /* latch on acknowledge */ IAKO = IAKI & !INT_ARB_WON; /* pass on if not for us */ append DAB_VECT = IAKI & INT_ARB_WON & VECTOR; /* place vector on TS bus */ append DAB.OE = IAKI & INT_ARB_WON; append RPLY = IAKI & INT_ARB_WON; /* reply to acknowledge */ /* CSR - Control and Status Register */ /* read cycle */ $ifdef DMA append [DAB10..15] = QBR & CS_COM & [EXT_DMAADR0..5]; $endif append DAB7 = QBR & CS_COM & DINTRQ; /* disk interrupt request line */ append DAB6 = QBR & CS_COM & INT_ENABLE; /* interrupt enable */ append DAB5 = QBR & CS_COM & IORDY_ENABLE; /* disk IORDY control enable */ append DAB4 = QBR & CS_COM & ATA_IRQ; /* disk interrupt pending */ append DAB0 = QBR & CS_COM; /* LSB always reads as 1 */ /* write cycle */ $ifdef DMA [EXT_DMAADR0..5].AR = INIT; $endif INT_ENABLE.D = DAB6; /* INT_ENABLE.CK = !(QBW & CS_COM); */ INT_ENABLE.CK = !(CS_COM & DOUT); ieck = !(CS_COM & DOUT); INT_ENABLE.AR = INIT; IORDY_ENABLE.D = DAB5; /* IORDY_ENABLE.CK = !(QBW & CS_COM); */ IORDY_ENABLE.CK = !(CS_COM & DOUT); IORDY_ENABLE.AR = INIT; /* Vector Register */ append DAB_VECT = QBR & CS_VECT & VECTOR; VECTOR.D = DAB_VECT; VECTOR.CK = !(QBW & CS_VECT); $ifdef DMA /* N-Bit, loadable counter macro that uses the T-type registers */ /* LD: jam DIN to Q if true during CLK pulse */ /* CNT: increment Q by 1 if true during CLK pulse */ /* DIN: jam input */ /* Q: N-bit state register */ /* N: bits in counter register */ /* CLK: jam or increment triggered on trail edge */ $macro counter LD CNT DIN Q N CLK $repeat i = [0..{N - 1}] Q{i}.T = LD & !CNT & !DIN{i} & Q{i} /* jam logic */ # LD & !CNT & DIN{i} & !Q{i}; /* toggle if DINn != Qn */ $repend append Q{0}.T = !LD & CNT; /* LSB toggles on every count */ $repeat i = [{1}..{N - 1}] append Q{i}.T = !LD & CNT & [Q{0}..{i - 1}]:&; /* toggle if DINn != Qn */ $repend [Q{0}..{N - 1}].ck = !((LD # CNT) & CLK); $mend /* DMA Address Register */ append DAB = QBR & CS_DMAADR & DMAADR; counter(CS_DMAADR, RSRVD, DAB, DMAADR, 16, DOUT); /* DMA Count Register */ append DAB_LOW = QBR & CS_DMACNT & DMACNT; counter(CS_DMACNT, RSRVD, DAB, DMACNT, 8, DOUT); /* Extended DMA Address Register */ /* read register as top of CSR -- see CSR section */ /* load register as top of CSR */ $repeat i = [0..5] EXT_DMAADR{i}.T = CS_COM & !RSRVD & !DAB{i + 10} & EXT_DMAADR{i} # CS_COM & !RSRVD & DAB{i + 10} & !EXT_DMAADR{i}; $repend append EXT_DMAADR0.T = !CS_COM & RSRVD & DMAADR:&; $repeat i = [1..5] append EXT_DMAADR{i}.T = !CS_COM & RSRVD & [EXT_DMAADR{0}..{i - 1}]:& & DMAADR:&; $repend [EXT_DMAADR0..5].CK = !((CS_COM # RSRVD) & DOUT); $endif /* Miscellaneous logic */ SYNC_LITE = !SYNC;