DIRECTORY XOps, PrincOps USING [zMISC]; XBus: CEDAR DEFINITIONS = BEGIN MBusTimeout: SIGNAL; IORead: PROC [mbFrom: LONG POINTER] RETURNS [data: WORD] = TRUSTED INLINE { ReadMBus[8604H, @data, mbFrom, 2, 1]; }; IOWrite: PROC [mbTo: LONG POINTER, data: WORD] = TRUSTED INLINE { WriteMBus[8508H, @data, mbTo, 2, 1]; }; MemRead: PROC [mbFrom: LONG POINTER] RETURNS [data: WORD] = TRUSTED INLINE { ReadMBus[8A01H, @data, mbFrom, 2, 1]; }; MemWrite: PROC [mbTo: LONG POINTER, data: WORD] = TRUSTED INLINE { WriteMBus[8902H, @data, mbTo, 2, 1]; }; MoveToMB: PROC [from, to: LONG POINTER, wordCount: CARDINAL] = TRUSTED INLINE { WriteMBus[8902H, from, to, 2, wordCount]; }; MoveFromMB: PROC [from, to: LONG POINTER, wordCount: CARDINAL] = TRUSTED INLINE { ReadMBus[8A01H, to, from, 2, wordCount]; }; BusMasterRead: PROC [mbFrom: LONG POINTER] RETURNS [data: WORD] = TRUSTED INLINE { ReadMBus[404H, @data, mbFrom, 2, 1]; }; BusMasterWrite: PROC [mbTo: LONG POINTER, data: WORD] = TRUSTED INLINE { WriteMBus[408H, @data, mbTo, 2, 1]; }; PCIORead1B: PROC [mbFrom: LONG POINTER] RETURNS [data: WORD] = TRUSTED INLINE { ReadMBus[4H, @data, mbFrom, 2, 1]; }; PCIOWrite1B: PROC [mbTo: LONG POINTER, data: WORD] = TRUSTED INLINE { WriteMBus[8H, @data, mbTo, 2, 1]; }; PCMemRead1B: PROC [mbFrom: LONG POINTER] RETURNS [data: WORD] = TRUSTED INLINE { ReadMBus[1H, @data, mbFrom, 2, 1]; }; PCMemWrite1B: PROC [mbTo: LONG POINTER, data: WORD] = TRUSTED INLINE { WriteMBus[2H, @data, mbTo, 2, 1]; }; PCIORead: PROC [mbFrom: LONG POINTER] RETURNS [data: WORD] = TRUSTED INLINE { ReadIBMBus[4H, @data, mbFrom, 1, 1]; }; PCIOWrite: PROC [mbTo: LONG POINTER, data: WORD] = TRUSTED INLINE { WriteIBMBus[8H, @data, mbTo, 1, 1]; }; PCMemRead: PROC [mbFrom: LONG POINTER] RETURNS [data: WORD] = TRUSTED INLINE { ReadIBMBus[1H, @data, mbFrom, 1, 1]; }; PCMemWrite: PROC [mbTo: LONG POINTER, data: WORD] = TRUSTED INLINE { WriteIBMBus[2H, @data, mbTo, 1, 1]; }; PCMoveToMB: PROC [from, to: LONG POINTER, wordCount: CARDINAL] = TRUSTED INLINE { WriteIBMBus[2H, from, to, 1, wordCount]; }; PCMoveFromMB: PROC [from, to: LONG POINTER, wordCount: CARDINAL] = TRUSTED INLINE { ReadIBMBus[1H, to, from, 1, wordCount]; }; PCRefreshOn: PROC []; ReadL: PROC [add: POINTER] RETURNS [WORD] = TRUSTED MACHINE CODE {PrincOps.zMISC, XOps.aReadL}; ReadM: PROC [add: POINTER] RETURNS [WORD] = TRUSTED MACHINE CODE {PrincOps.zMISC, XOps.aReadM}; WriteL: PROC [add: POINTER, data: WORD] = TRUSTED MACHINE CODE {PrincOps.zMISC, XOps.aWriteL}; WriteM: PROC [add: POINTER, data: WORD] = TRUSTED MACHINE CODE {PrincOps.zMISC, XOps.aWriteM}; WriteMBus: PROC [controlData: WORD, from, to: LONG POINTER, byteInterval, wordCnt: CARDINAL] = TRUSTED MACHINE CODE {PrincOps.zMISC, XOps.aWriteMBus}; ReadMBus: PROC [controlData: WORD, to, from: LONG POINTER, byteInterval, wordCnt: CARDINAL] RETURNS [] = TRUSTED MACHINE CODE {PrincOps.zMISC, XOps.aReadMBus}; WriteIBMBus: PROC [controlData: WORD, from, to: LONG POINTER, byteInterval, wordCnt: CARDINAL] = TRUSTED MACHINE CODE {PrincOps.zMISC, XOps.aWriteIBMBus}; ReadIBMBus: PROC [controlData: WORD, to, from: LONG POINTER, byteInterval, wordCnt: CARDINAL] RETURNS [] = TRUSTED MACHINE CODE {PrincOps.zMISC, XOps.aReadIBMBus}; END. XBus.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Last Edited by: Gasbarro, April 18, 1986 11:45:16 am PST Tim Diebert: July 15, 1986 12:29:49 pm PDT Fiala: August 21, 1986 3:18:34 pm PDT Note: For Multibus IORead and IOWrite operations the Busmaster card consumes the low 256 bytes of the IO address space. For PC operations the entire IO address space is free for use. Use BusmasterRead and BusmasterWrite to access the on board devices. The Multibus1/PCBus block-moving opcodes cause an opcode trap when an MBus timeout occurs due to the absence of an acknowledgment during a 10 microsecond wait; this is considered a fatal hardware malfunction. The opcode trap procedure executed when this occurs raises this signal. Note: For Multibus IORead and IOWrite operations the Busmaster card consumes the low 256 bytes of the IO address space. For PC operations the entire IO address space is free for use. Use BusmasterRead and BusmasterWrite to access the on board devices. These procedures read/write one byte from/to the PC bus using bits [8..15] in the VM word. Note that this is done using the Multibus1 opcodes. These procedures read/write one 16-bit word from/to the PC bus using the special block move opcodes for the PC bus. These procedures move blocks of 16-bit words. Initializes a DMA controller on the Busmaster card to perform continuous memory refresh on the IBM-PC bus. These routines manipulate registers on the XBus interface card. You shouldn't need to use them. The ReadMBus and WriteMBus opcodes move blocks of data between the MultiBus1 and Dandelion VM or a single byte between the PC bus and Dandelion VM. The ReadIBMBus and WriteIBMBus opcodes move blocks of words between the PCBus and Dandelion VM. Most microcode is common to all opcodes. Clients will ordinarily use the opcodes indirectly by calling the other INLINE procedures above in which the controlData parameter is specified. byteInterval is the separation in bytes between consecutive source words (MBus) or bytes (PCBus). Timing ~= 10 clicks + 6 clicks/word + 3 clicks/page cross + 2 clicks/ackwait ~= 2.5 microseconds/word Timing ~= 10 clicks + 8 clicks/word + 3 clicks/page cross + 2 clicks/ackwait ~= 3.3 microseconds/word Timing ~= 10 clicks + 11 clicks/word + 3 clicks/page cross + 2 clicks/ackwait ~= 4.5 microseconds/word Timing ~= 10 clicks + 15 clicks/word + 3 clicks/page cross + 2 clicks/ackwait ~= 6.2 microseconds/word The implementation of the opcodes is shown by the following pseudo-program Read/Write M/PC Bus: PROC [controlData: WORD, VMaddr, MBaddr: LONG PONTER, wordCount: CARDINAL] ~ { IF wordCount = 0 THEN RETURN; WriteM[mBusCtl {2}, controlData]; WriteM[mBusAddr {3}, HighHalf[MBaddr]]; GOTO[Enter]; LP: IF (wordCount _ wordCount - 1) = 0 THEN RETURN; IF (LowHalf[MBaddr] _ LowHalf[MBaddr] + byteInterval) carries THEN { HighHalf[MBaddr] _ HighHalf[MBaddr] + 1; WriteM[mBusAddr {3}, HighHalf[MBaddr]]; }; IF (VMaddr _ VMaddr + 1) crosses page boundary THEN { Enter: Remap[VMaddr]; --Different for reads and writes }; IF interrupt pending and enabled THEN service it; outData: WORD _ VMaddr^; WriteL[1BusAddr {3}, LowHalf[MBaddr]]; WriteL[1BusOutData {2}, outData]; --or outData LCY 8 if PCBus For 10 microcoseconds loop; after that return error. Normally ack is given in 0.5 to 1.0 microseconds. FOR I: CARDINAL IN [0..12) DO IF BITAND[ReadM[mBusCtl {2}], 4] # 0 THEN { --Ack received XXX; --Code specific to the opcode }; ENDLOOP; --MISC opcode trap to a procedure which raises the MBusTimeout signal Trap[MBusTimeout]; }; For WriteMBus XXX = GOTO[Lp]; For ReadMBus XXX = VMaddr^ _ ReadL[1BusInData]; GOTO[Lp]; For WritePCBus XXX = IF (LowHalf[MBaddr] _ LowHalf[MBaddr] + byteInterval) carries THEN { HighHalf[MBaddr] _ HighHalf[MBaddr] + 1; WriteM[mBusAddr {3}, HighHalf[MBaddr]]; }; WriteL[1BusAddr {3}, LowHalf[MBaddr]]; WriteL[1BusOutData {2}, outData]; --Write the odd byte FOR I: CARDINAL IN [0..12) DO IF BITAND[ReadM[mBusCtl {2}], 4] # 0 THEN GOTO[Lp]; --Ack received ENDLOOP; Trap[MBusTimeout]; For ReadPCBus XXX = evenByte: WORD _ BITSHIFT[ReadL[1BusInData {2}], 8]; IF (LowHalf[MBaddr] _ LowHalf[MBaddr] + byteInterval) carries THEN { HighHalf[MBaddr] _ HighHalf[MBaddr] + 1; WriteM[mBusAddr {3}, HighHalf[MBaddr]]; }; WriteL[1BusAddr {3}, LowHalf[MBaddr]]; WriteL[1BusOutData {2}, garbage]; FOR I: CARDINAL IN [0..12) DO IF BITAND[ReadM[mBusCtl {2}], 4] # 0 THEN { --Ack received VMaddr^ _ BITOR[evenByte, BITAND[ReadL[1BusInData {2}], 377B]]; GOTO[Lp]; }; ENDLOOP; Trap[MBusTimeout]; --Trap through the MISC opcode trap table Κ[˜šœ ™ Jšœ Οmœ7™BJ™8Icode™*K™%—K™šΟk ˜ Jšœ˜Jšœ žœ ˜—J™šœžœž˜J™J™όK™J˜Jšœ™™™JšΟn œžœ˜J˜J™όšŸœžœ žœžœžœžœžœž˜KKšœ%˜%Kšžœ˜K˜—š Ÿœžœžœžœžœžœž˜AKšœ$˜$Kšžœ˜K˜—šŸœžœ žœžœžœžœžœžœ˜LKšœ%˜%Kšœ˜K˜—š Ÿœžœž œžœž˜BKšœ$˜$Kšžœ˜—K˜šŸœžœ žœžœ žœžœžœ˜PKšœ)˜)Kšœ˜—K˜šŸ œžœ žœžœ žœžœžœ˜RKšœ(˜(Kšœ˜—J˜šŸ œžœ žœžœžœžœžœž˜RKšœ$˜$Jšžœ˜J˜—š Ÿœžœžœžœžœžœž˜HKšœ#˜#Jšžœ˜K˜K˜—Kšœ™šŸ œžœ žœžœžœžœžœž˜OKšœ"˜"Kšžœ˜K˜—šŸ œžœžœžœžœžœžœ˜EKšœ!˜!Kšœ˜K˜—šŸ œžœ žœžœžœžœžœžœ˜PKšœ"˜"Kšœ˜K˜—šŸ œžœžœžœžœžœžœ˜FKšœ!˜!Kšœ˜—K˜K˜Kšœs™sšŸœžœ žœžœžœžœžœž˜MKšœ$˜$Kšžœ˜K˜—šŸ œžœžœžœžœžœžœ˜CKšœ#˜#Kšœ˜K˜—šŸ œžœ žœžœžœžœžœžœ˜NKšœ$˜$Kšœ˜K˜—š Ÿ œžœž œžœž˜DKšœ#˜#Kšžœ˜—K˜Kšœ-™-šŸ œžœ žœžœ žœžœžœ˜RKšœ(˜(Kšžœ˜—K˜šŸ œžœ žœžœ žœžœžœ˜TKšœ'˜'Kšœ˜—K˜J˜šŸ œžœ˜J™j—J˜J˜Jšœ_™_J˜JšŸœžœžœžœžœžœžœžœ˜_J˜JšŸœžœžœžœžœžœžœžœ˜_J˜JšŸœžœžœžœžœžœžœ ˜^J˜JšŸœžœžœžœžœžœžœ ˜^—˜Kšœ“™“K™Kšœf™fKšŸ œžœžœ žœžœžœžœžœžœ#˜–K™Kšœg™gKšŸœžœžœ žœžœžœžœžœžœžœ"˜ŸK™Kšœj™jKšŸ œžœžœ žœžœžœžœžœžœ%˜šK™Kšœi™iKšŸ œžœžœ žœžœžœžœžœžœžœ$˜£K™KšœJ™JK™šœc™cJšœ™Jšœ!™!Jšœ'™'J™ J™Jšœ™Jšœ/™/™DJ™(J™'J™—Jšœ5™5šœ™Jšœ0™0Jšœ™—Jšœ1™1Jšœ™Jšœ&™&Jšœ>™>Jšœg™gšœ™šœ;™;Jšœ#™#J™—Jšœ™—JšœG™GJšœ™Kšœ™K™™K™ —K™™K™&—K™™™DK™(K™'K™—K™&K™6šœ™JšœC™CJšœ™—Jšœ™—K™™K™4™DK™(K™'K™—K™&K™!šœ™šœ:™:Jšœ?™?Jšœ ™ J™—Jšœ™—Jšœ=™=—K™—Jšžœ˜—J˜—…— Ό&+