<> <> <> <> 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.