DIRECTORY RoseTypes, RoseCreate, IO, Dragon, DragonFP, PrintTV, AMBridge; FP: CEDAR PROGRAM IMPORTS RoseCreate, IO, Dragon, DragonFP, PrintTV, AMBridge = BEGIN OPEN RoseTypes; CSLoad: TYPE = DragonFP.CSLoad; CSUnload: TYPE = DragonFP.CSUnload; PBusFaults: TYPE = Dragon.PBusFaults; RegisterCells: PROC = BEGIN END; otherss: SymbolTable _ RoseCreate.GetOtherss["FP.pass"]; FPDeviceArgs: PUBLIC TYPE = RECORD [ type: FPDeviceType]; OldFPDevice: TYPE = RECORD [args: FPDeviceArgs, ct: CellType]; oldFPDevice: LIST OF OldFPDevice _ NIL; FPDevice: PUBLIC PROC [args: FPDeviceArgs] RETURNS [ct: CellType] = BEGIN FOR old: LIST OF OldFPDevice _ oldFPDevice, old.rest WHILE old # NIL DO IF old.first.args = args THEN RETURN [old.first.ct] ENDLOOP; ct _ RoseCreate.RegisterCellType[name: FPDeviceName[args], expandProc: NIL, ioCreator: CreateFPDeviceIO, initializer: InitializeFPDevice, evals: [EvalSimple: FPDeviceEvalSimple], tests: LIST[], ports: CreateFPDevicePorts[args], driveCreator: CreateFPDeviceDrive, typeData: NEW [FPDeviceArgs _ args]]; oldFPDevice _ CONS[[args, ct], oldFPDevice]; END; FPDeviceName: PROC [args: FPDeviceArgs] RETURNS [name: ROPE] = { to: IO.STREAM _ IO.ROS[]; to.PutRope["FPDevice"]; TRUSTED {PrintTV.Print[tv: AMBridge.TVForReferent[NEW [FPDeviceArgs _ args]], put: to]}; name _ IO.RopeFromROS[to]}; CreateFPDevicePorts: PROC [args: FPDeviceArgs] RETURNS [ports: Ports] = {ports _ RoseCreate.PortsFromFile["FP.FPDevice.rosePorts"]}; FPDeviceIORef: TYPE = REF FPDeviceIORec; FPDeviceIORec: TYPE = MACHINE DEPENDENT RECORD [ CSLd3AB(0): CSLoad, CSUn2AB(1): CSUnload, EPFaultB(2): PBusFaults, EPData(3): ARRAY [0..2) OF CARDINAL, KBus(5): ARRAY [0..2) OF CARDINAL, PhA(7): BOOLEAN, PhB(8): BOOLEAN, InstrCountAB(9): ARRAY [0..2) OF CARDINAL]; FPDeviceDriveRef: TYPE = REF FPDeviceDriveRec; FPDeviceDriveRec: TYPE = RECORD [tag: DriveTagType, s: PACKED ARRAY FPDevicePort OF DriveLevel]; FPDevicePort: TYPE = MACHINE DEPENDENT { CSLd3AB, CSUn2AB, EPFaultB, EPData, KBus, PhA, PhB, InstrCountAB}; CreateFPDeviceIO: PROC [ct: CellType] RETURNS [ioAsAny: REF ANY] --IOCreator-- = { ioAsAny _ NEW[FPDeviceIORec]; }; CreateFPDeviceDrive: PROC [ct: CellType] RETURNS [driveAsAny: REF ANY] --DriveCreator-- = { driveAsAny _ NEW[FPDeviceDriveRec]; }; FPDeviceStateRef: TYPE = REF FPDeviceStateRec; FPDeviceStateRec: TYPE = RECORD [ f0, f1, freg: DragonFP.Function, mode: DragonFP.Mode, x0, x1: Dragon.HexWord, aM, aL, bM, bL: Dragon.HexWord, arM, arL, brM, brL: Dragon.HexWord, aluCSL1, mulCSL1: DragonFP.CSLoad, aluCSU1, mulCSU1: DragonFP.CSUnload, aluCSU2, mulCSU2: DragonFP.CSUnload, load0, load1: DragonFP.Load, unload0, unload1: DragonFP.Unload, aluST0, mulST0: Dragon.PBusFaults, aluST1, mulST1: Dragon.PBusFaults, aluDM, mulDM: Dragon.HexWord, aluDL, mulDL: Dragon.HexWord, aluZ, mulZ: Dragon.HexWord ]; InitializeFPDevice: Initializer = { IF leafily THEN BEGIN args: REF FPDeviceArgs _ NARROW [cell.type.typeData]; state: FPDeviceStateRef _ NEW[FPDeviceStateRec]; cell.realCellStuff.state _ state; END; }; FPDeviceEvalSimple: CellProc = BEGIN args: REF FPDeviceArgs _ NARROW[cell.type.typeData]; newIO: FPDeviceIORef _ NARROW[cell.realCellStuff.newIO]; state: FPDeviceStateRef _ NARROW[cell.realCellStuff.state]; BEGIN OPEN newIO, args, state; IF PhA THEN { clocked _ FALSE; load0 _ LOOPHOLE[BitOps.ECFD[KBus, 32, 16+ 2, 5]]; f0 _ LOOPHOLE[BitOps.ECFD[KBus, 32, 16+ 7, 1]]; unload0 _ LOOPHOLE[BitOps.ECFD[KBus, 32, 16+10, 6]]; x0 _ Dragon.LFD[EPData]; }; IF NOT PhA AND NOT clocked THEN { clocked _ TRUE; cycle _ MAX[cycle-1, -1]; -- off at -1 IF cycle=0 THEN csU2 _ csU1; [[aluDM, aluDL], aluST0] _ (SELECT type FROM Alu => DragonFP.ALU [[arM,arL], [brM,brL], freg, mode, aArg, bArg], Mult => DragonFP.MUL [[arM,arL], [brM,brL], freg, mode, aArg, bArg]); csU1 _ CSUn2AB; IF CSUn2AB=unload THEN SELECT code FROM fpLdSglAUnMsw => {ibus _ dm}; fpLdLswAUnLsw => {ibus _ dl}; fpLdMswAUnMsw => {ibus _ dm}; ENDCASE => Dragon.Assert[FALSE, "Unimplemented unload code"] }; IF CSLd3AB=load THEN { SELECT code FROM fpLdSglBSt => {brS _ ibus; freg_f1; start_TRUE}; fpLdLswB => {brL _ ibus; start_FALSE}; fpLdLswBSt => {brL _ ibus; freg_f1; start_TRUE}; fpLdMswB => {brM _ ibus; start_FALSE}; fpLdMswBSt => {brM _ ibus; freg_f1; start_TRUE}; fpLdSglAUnMsw => {arS _ ibus; unload_msw; start_FALSE}; fpLdLswAUnLsw => {arL _ ibus; unload_lsw; start_FALSE}; fpLdMswAUnMsw => {arM _ ibus; unload_msw; start_FALSE}; delGamBetAlp => mode _ DragonFP.SetMode[mode, f1]; ENDCASE => Dragon.Assert[FALSE, "Unimplemented load code"] }; aluZ _ IF unload1=msw THEN aluDM ELSE aluDL; mulZ _ IF unload1=msw THEN mulDM ELSE mulDL; unload1 _ unload0; aluST1 _ aluST0; mulST1 _ mulST0; IF mulCSL1=load THEN { }; SELECT load1 FROM none => { }; func => {arM_aM; arL_aL; brM_bM; brL_bL; freg_f1}; bLo => {arM_aM; arL_aL; brM_bM; brL_bL_x1; freg_f1}; bHi => {arM_aM; arL_aL; brM_bM_x1; brL_bL; freg_f1}; aLo => {arM_aM; arL_aL_x1; brM_bM; brL_bL; freg_f1}; aHi => {arM_aM_x1; arL_aL; brM_bM; brL_bL; freg_f1}; delGamBetAlp => mode _ DragonFP.SetMode[mode, f1]; ENDCASE => Dragon.Assert[FALSE, "Unimplemented load code"] }; [[aluDM, aluDL], aluST0] _ DragonFP.ALU[[arM,arL], [brM,brL], freg, mode]; [[mulDM, mulDL], mulST0] _ DragonFP.MUL[[arM,arL], [brM,brL], freg, mode]; f1 _ f0; x1 _ x0; aluCSL1 _ FPCSLdAlu3AB; mulCSL1 _ FPCSLdMult3AB; load1 _ load0 }; IF PhB THEN { IF aluCSU2=unload THEN { EPData _ Dragon.LTD[aluZ]; EPFaultB _ aluST1; IF log # IO.noWhereStream THEN { log.PutF["\n%5g", IO.card[ Dragon.LFD[InstrCountAB] ] ]; log.PutF[" FP-Alu:%08x", IO.card[ Dragon.LFD[EPData] ] ]; log.PutF[" Status:%01x", IO.card[ LOOPHOLE[aluST1, CARDINAL] ] ] } }; IF mulCSU2=unload THEN { EPData _ Dragon.LTD[mulZ]; EPFaultB _ mulST1; IF log # IO.noWhereStream THEN { log.PutF["\n%5g", IO.card[ Dragon.LFD[InstrCountAB] ] ]; log.PutF[" FP-Mul:%08x", IO.card[ Dragon.LFD[EPData] ] ]; log.PutF[" Status:%01x", IO.card[ LOOPHOLE[mulST1, CARDINAL] ] ] } }; }; END; END; FPArgs: PUBLIC TYPE = RECORD [ logRef: REF IO.STREAM]; OldFP: TYPE = RECORD [args: FPArgs, ct: CellType]; oldFP: LIST OF OldFP _ NIL; FP: PUBLIC PROC [args: FPArgs] RETURNS [ct: CellType] = BEGIN FOR old: LIST OF OldFP _ oldFP, old.rest WHILE old # NIL DO IF old.first.args = args THEN RETURN [old.first.ct] ENDLOOP; ct _ RoseCreate.RegisterCellType[name: FPName[args], expandProc: FPExpand, ioCreator: CreateFPIO, initializer: NIL, evals: [], tests: LIST[], ports: CreateFPPorts[args], driveCreator: CreateFPDrive, typeData: NEW [FPArgs _ args]]; oldFP _ CONS[[args, ct], oldFP]; END; FPName: PROC [args: FPArgs] RETURNS [name: ROPE] = { to: IO.STREAM _ IO.ROS[]; to.PutRope["FP"]; TRUSTED {PrintTV.Print[tv: AMBridge.TVForReferent[NEW [FPArgs _ args]], put: to]}; name _ IO.RopeFromROS[to]}; CreateFPPorts: PROC [args: FPArgs] RETURNS [ports: Ports] = {ports _ RoseCreate.PortsFromFile["FP.FP.rosePorts"]}; FPIORef: TYPE = REF FPIORec; FPIORec: TYPE = MACHINE DEPENDENT RECORD [ FPCSLdAlu3AB(0): CSLoad, FPCSLdMult3AB(1): CSLoad, FPCSUnAlu2AB(2): CSUnload, FPCSUnMult2AB(3): CSUnload, EPFaultB(4): PBusFaults, EPData(5): ARRAY [0..2) OF CARDINAL, KBus(7): ARRAY [0..2) OF CARDINAL, PhA(9): BOOLEAN, PhB(10): BOOLEAN, InstrCountAB(11): ARRAY [0..2) OF CARDINAL]; FPDriveRef: TYPE = REF FPDriveRec; FPDriveRec: TYPE = RECORD [tag: DriveTagType, s: PACKED ARRAY FPPort OF DriveLevel]; FPPort: TYPE = MACHINE DEPENDENT { FPCSLdAlu3AB, FPCSLdMult3AB, FPCSUnAlu2AB, FPCSUnMult2AB, EPFaultB, EPData, KBus, PhA, PhB, InstrCountAB, (15)}; CreateFPIO: PROC [ct: CellType] RETURNS [ioAsAny: REF ANY] --IOCreator-- = { ioAsAny _ NEW[FPIORec]; }; CreateFPDrive: PROC [ct: CellType] RETURNS [driveAsAny: REF ANY] --DriveCreator-- = { driveAsAny _ NEW[FPDriveRec]; }; FPExpand: PROC [thisCell: Cell, to: ExpansionReceiver] --ExpandProc-- = { args: REF FPArgs _ NARROW[thisCell.type.typeData]; {OPEN args; PrivateLookupNode: PROC [name: ROPE] RETURNS [node: Node] = {node _ RoseCreate.LookupNode[from: thisCell, path: LIST[name]]}; FPCSLdAlu3AB: Node _ PrivateLookupNode["FPCSLdAlu3AB"]; FPCSLdMult3AB: Node _ PrivateLookupNode["FPCSLdMult3AB"]; FPCSUnAlu2AB: Node _ PrivateLookupNode["FPCSUnAlu2AB"]; FPCSUnMult2AB: Node _ PrivateLookupNode["FPCSUnMult2AB"]; EPFaultB: Node _ PrivateLookupNode["EPFaultB"]; EPData: Node _ PrivateLookupNode["EPData"]; KBus: Node _ PrivateLookupNode["KBus"]; PhA: Node _ PrivateLookupNode["PhA"]; PhB: Node _ PrivateLookupNode["PhB"]; InstrCountAB: Node _ PrivateLookupNode["InstrCountAB"]; others: SymbolTable _ RoseCreate.GetOthers[otherss, "FP"]; [] _ to.class.CellInstance[erInstance: to.instance, instanceName: "fpAlu", typeName: FPDevice[[type:Alu]].name, other: RoseCreate.GetOther[others, "fpAlu"], interfaceNodes: "CSLd3AB:FPCSLdAlu3AB, CSUn2AB:FPCSUnAlu2AB"]; [] _ to.class.CellInstance[erInstance: to.instance, instanceName: "fpMul", typeName: FPDevice[[type:Mul]].name, other: RoseCreate.GetOther[others, "fpMul"], interfaceNodes: "CSLd3AB:FPCSLdMult3AB, CSUn2AB:FPCSUnMult2AB"]; }; }; log: IO.STREAM _ IO.noWhereStream; clocked: BOOL _ FALSE; RegisterCells[]; END. šFP.Mesa created by RoseTranslate 2.8.8 of January 28, 1985 2:26 pm PST from FP.Rose of February 8, 1985 4:49:19 pm PST created for curry.pa created at February 8, 1985 4:49:23 pm PST Signal Type decls The following assumes that the D regs can be made transparent - Check this It may be that load nop's may be required between the load and unloads in order to make sure that D gets clocked. The timing is such that the nop load must occur one cycle before the unload which means that it must occur two cycles before the unload in the microcode stream since unloads are driven by IPipe one cycle before loads. TEN is tied to phB' explicitly requested CEDAR: Κ d˜Icodešœ™Kšœn™nKšœ™Kšœ*™*K˜K˜šΟk ˜ Kšœœ&˜?—K˜šΡbklœœ˜Kšœ œ'˜=—K˜šœ˜ K˜ —K˜šœ™Kšœœ˜Kšœ œ˜#Kšœ œ˜%K˜—K˜šΟn œœ˜Kš˜Kšœ˜—K˜8K˜šœœœœ˜$K˜—K˜Kšœ œœ$˜>Kšœ œœœ˜'šŸœœœœ˜CKš˜š œœœ%œœ˜GKšœœœ˜3Kšœ˜—˜:Kšœ œ˜K˜=K˜(Kšœœ˜K˜!K˜"Kšœ œ˜%—Kšœœ˜,Kšœ˜—K˜šŸ œœœœ˜@Kš œœœœœ˜1Kšœ+œ#˜XKšœœ˜—K˜KšŸœœœN˜„K˜Kšœœœ˜(š œœœ œœ˜0K˜K˜K˜Kšœ œœœ˜$Kšœ œœœ˜"Kšœœ˜Kšœœ˜Kšœœœœ˜+—K˜Kšœœœ˜.Kš œœœœœœ ˜`šœœœ œ˜(K˜B—K˜š Ÿœœœ œœΟc œ˜RKšœ œ˜K˜—K˜š Ÿœœœœœ œ˜[Kšœ œ˜#K˜—K˜Kšœœœ˜.šœœœ˜!J™J˜$J˜J˜J˜J˜J˜#J˜J˜$J˜&J˜&J˜J˜ J˜$J˜J˜$J˜$J˜J˜J˜J˜J˜J˜J˜K˜—K˜˜#šœ ˜Kš˜Kšœœœ˜5Kšœœ˜0K˜!Kšœ˜—K˜—K˜˜Kš˜Kšœœœ˜4Kšœœ˜8šœœ˜;šœœ˜J˜šœœ˜ Jšœ œ˜J˜Jšœ œœ˜3Jšœœœ˜1Jšœ œœ˜4J˜Jšœœ ˜J˜—J™š œœœœ œ˜!J˜Jšœ œ˜Jšœœ  ˜&Jšœ ˜J˜ šœœ˜-Jšœœ0˜DJšœœ1˜F—J˜šœ˜šœ˜J˜J˜J˜Jšœœ!˜?——J˜šœœ˜šœ˜Jšœ.œ˜4Jšœ&œ˜-Jšœ.œ˜4Jšœ&œ˜-Jšœ.œ˜4Jšœ0œ˜7Jšœ1œ˜8Jšœ0œ˜7J˜3Jšœœ˜=——J˜Jšœœ œœ˜-Jšœœ œœ˜-J˜J˜J˜J˜J˜Jšœœ˜šœ˜J˜ J˜9J˜5J˜5J˜5J˜5J˜3Jšœœ˜=—J˜J™JJ™ΜJšœ%œ#˜KJšœ$œ#˜JJ˜J˜ J˜ J˜J˜J˜ J˜J˜—šœœ˜ J˜J™J˜šœœ˜Jšœœ˜J˜šœœœ˜ Jšœœœ˜:Jšœœœ ˜:Jšœœœ œ ˜F——šœœ˜Jšœœ˜J˜šœœœ˜ Jšœœœ˜:Jšœœœ ˜:Jšœœœ œ ˜F——J˜J˜——Kšœ˜—Kšœ˜—K˜šœœœœ˜Kšœœœœ˜—K˜Kšœœœ˜2Kšœœœ œ˜šœœœœ˜7Kš˜š œœœœœ˜;Kšœœœ˜3Kšœ˜—˜4K˜Kšœ$œ˜(K˜ Kšœœ˜K˜K˜Kšœ œ˜—Kšœœ˜ Kšœ˜—K˜šŸœœœœ˜4Kš œœœœœ˜+Kšœ+œ˜RKšœœ˜—K˜KšŸ œœœH˜rK˜Kšœ œœ ˜š œ œœ œœ˜*K˜K˜K˜K˜K˜Kšœ œœœ˜$Kšœ œœœ˜"Kšœœ˜Kšœ œ˜Kšœœœœ˜,—K˜Kšœ œœ ˜"Kš œ œœœœœ ˜Tšœœœ œ˜"K˜p—K˜š Ÿ œœœ œœ  œ˜LKšœ œ ˜K˜—K˜š Ÿ œœœœœ œ˜UKšœ œ ˜K˜—K˜šŸœœ) œ˜Išœœ œ˜2Kšœœ˜ Kš ŸœœœœDœ ˜}K˜7K˜9K˜7K˜9K˜/K˜+K˜'K˜%K˜%K˜7K˜:K˜ΫK˜έK˜—K˜—K˜šœ™Jšœœœœ˜"Jšœ œœ˜—K˜K˜K˜K˜Kšœ˜—…—#π0ξ