<> <> <> DIRECTORY BasicLoadStateFormat USING[ LoadStateObject ], PrincOps USING[ GlobalFrameHandle ], LoadState USING[ Handle ], LoadStateFormat, WorldVM USING[ Address, CopyRead, LongRead, Read ], WVMPrivate USING[ WorldObject ]; WVMLoadState: MONITOR IMPORTS WorldVM EXPORTS LoadState--opaque type--, WorldVM--opaque type--, WVMPrivate = BEGIN World: TYPE = REF WorldObject; WorldObject: PUBLIC TYPE = WVMPrivate.WorldObject; GetLoadState: PUBLIC PROC[world: World, basic, real: WorldVM.Address] = BEGIN IF real # 0 THEN CopyRealLoadState[world, real] ELSE CopyBasicLoadState[world, basic]; END; --LoadState.--Object: PUBLIC TYPE = LoadStateFormat.Object; CopyRealLoadState: PROC[world: World, real: WorldVM.Address] = BEGIN loadState: REF Object = NEW[Object]; loadState.useCount _ 0; loadState.changeCount _ LOOPHOLE[WorldVM.LongRead[ world: world, addr: real + (LOOPHOLE[@loadState.changeCount,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address]) ]]; loadState.configTable _ CopyConfigTable[ world: world, from: WorldVM.LongRead[world, real + (LOOPHOLE[@loadState.configTable,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address])] ]; loadState.copyTable _ CopyCopyTable[ world: world, from: WorldVM.LongRead[world, real + (LOOPHOLE[@loadState.copyTable,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address])] ]; loadState.collisionTable _ CopyCollisionTable[ world: world, from: WorldVM.LongRead[world, real + (LOOPHOLE[@loadState.collisionTable,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address])] ]; WorldVM.CopyRead[ world: world, from: real + (LOOPHOLE[@loadState.gfht,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address]), to: @loadState.gfht, nwords: SIZE[ARRAY LoadStateFormat.HashIndex OF LoadStateFormat.Entry] ]; world.loadState _ loadState; END; CopyConfigTable: PROC[world: World, from: WorldVM.Address] RETURNS[to: REF LoadStateFormat.ConfigTable] = BEGIN minSize: CARDINAL = SIZE[LoadStateFormat.ConfigTable[0]]; temp: ARRAY [0..minSize) OF WORD; cheat: POINTER TO LoadStateFormat.ConfigTable = LOOPHOLE[@temp]; WorldVM.CopyRead[ world: world, from: from, to: @temp, nwords: minSize]; to _ NEW[LoadStateFormat.ConfigTable[cheat.length]]; to.nConfigs _ cheat.nConfigs; FOR i: NAT IN [0..to.nConfigs) DO to[i] _ CopyConfig[ world: world, from: WorldVM.LongRead[world, from + (LOOPHOLE[@to[i],WorldVM.Address]-LOOPHOLE[to,WorldVM.Address])] ]; ENDLOOP; END; CopyCopyTable: PROC[world: World, from: WorldVM.Address] RETURNS[to: REF LoadStateFormat.CopyTable] = BEGIN minSize: CARDINAL = SIZE[LoadStateFormat.CopyTable[0]]; temp: ARRAY [0..minSize) OF WORD; cheat: POINTER TO LoadStateFormat.CopyTable = LOOPHOLE[@temp]; WorldVM.CopyRead[ world: world, from: from, to: @temp, nwords: minSize]; to _ NEW[LoadStateFormat.CopyTable[cheat.length]]; to.nCopies _ cheat.nCopies; FOR i: NAT IN [0..to.nCopies) DO to[i].parent _ LOOPHOLE[WorldVM.Read[world, from + (LOOPHOLE[@to[i].parent,WorldVM.Address]-LOOPHOLE[to,WorldVM.Address])]]; to[i].copies _ CopyCopiesList[ world: world, from: WorldVM.LongRead[world, from + (LOOPHOLE[@to[i].copies,WorldVM.Address]-LOOPHOLE[to,WorldVM.Address])] ]; ENDLOOP; END; CopyCollisionTable: PROC[world: World, from: WorldVM.Address] RETURNS[to: REF LoadStateFormat.CollisionTable]= BEGIN minSize: CARDINAL = SIZE[LoadStateFormat.CollisionTable[0]]; temp: ARRAY [0..minSize) OF WORD; cheat: POINTER TO LoadStateFormat.CollisionTable = LOOPHOLE[@temp]; WorldVM.CopyRead[ world: world, from: from, to: @temp, nwords: minSize]; to _ NEW[LoadStateFormat.CollisionTable[cheat.length]]; to.nCollisions _ cheat.nCollisions; FOR i: NAT IN [0..to.nCollisions) DO to[i] _ CopyCollisionList[ world: world, from: WorldVM.LongRead[world, from + (LOOPHOLE[@to[i],WorldVM.Address]-LOOPHOLE[to,WorldVM.Address])] ]; ENDLOOP; END; CopyConfig: PROC[world: World, from: WorldVM.Address] RETURNS[to: REF LoadStateFormat.ConfigObject]= BEGIN minSize: CARDINAL = SIZE[LoadStateFormat.ConfigObject[0]]; temp: ARRAY [0..minSize) OF WORD; cheat: POINTER TO LoadStateFormat.ConfigObject = LOOPHOLE[@temp]; WorldVM.CopyRead[ world: world, from: from, to: @temp, nwords: minSize]; to _ NEW[LoadStateFormat.ConfigObject[cheat.length]]; to.bcd _ cheat.bcd; to.ref _ NIL; to.nModules _ cheat.nModules; WorldVM.CopyRead[ world: world, from: from + (LOOPHOLE[@to[0],WorldVM.Address]-LOOPHOLE[to,WorldVM.Address]), to: @to[0], nwords: to.nModules * SIZE[LoadStateFormat.ModuleEntry] ]; END; CopyCopiesList: PROC[world: World, from: WorldVM.Address] RETURNS[to: LIST OF PrincOps.GlobalFrameHandle _ NIL]= BEGIN fromPos: WorldVM.Address _ from; toPos: LIST OF PrincOps.GlobalFrameHandle _ NIL; dummy: LIST OF PrincOps.GlobalFrameHandle = CONS[first: NULL, rest: NIL]; firstOffset: CARDINAL = LOOPHOLE[@dummy.first,WorldVM.Address]-LOOPHOLE[dummy,WorldVM.Address]; restOffset: CARDINAL = LOOPHOLE[@dummy.rest,WorldVM.Address]-LOOPHOLE[dummy,WorldVM.Address]; UNTIL fromPos = 0--NIL-- DO this: PrincOps.GlobalFrameHandle = LOOPHOLE[WorldVM.Read[world, fromPos + firstOffset]]; new: LIST OF PrincOps.GlobalFrameHandle = CONS[first: this, rest: NIL]; IF to = NIL THEN to _ new ELSE toPos.rest _ new; toPos _ new; fromPos _ WorldVM.LongRead[world, fromPos + restOffset]; ENDLOOP; END; CopyCollisionList: PROC[world: World, from: WorldVM.Address] RETURNS[to: LIST OF LoadStateFormat.Entry _ NIL]= BEGIN fromPos: WorldVM.Address _ from; toPos: LIST OF LoadStateFormat.Entry _ NIL; dummy: LIST OF LoadStateFormat.Entry = CONS[first: NULL, rest: NIL]; firstOffset: CARDINAL = LOOPHOLE[@dummy.first,WorldVM.Address]-LOOPHOLE[dummy,WorldVM.Address]; restOffset: CARDINAL = LOOPHOLE[@dummy.rest,WorldVM.Address]-LOOPHOLE[dummy,WorldVM.Address]; UNTIL fromPos = 0--NIL-- DO this: LoadStateFormat.Entry; new: LIST OF LoadStateFormat.Entry; WorldVM.CopyRead[ world: world, from: fromPos + firstOffset, to: @this, nwords: SIZE[LoadStateFormat.Entry]]; new _ CONS[first: this, rest: NIL]; IF to = NIL THEN to _ new ELSE toPos.rest _ new; toPos _ new; fromPos _ WorldVM.LongRead[world, fromPos + restOffset]; ENDLOOP; END; CopyBasicLoadState: PROC[world: World, basic: WorldVM.Address] = BEGIN minSize: CARDINAL = SIZE[BasicLoadStateFormat.LoadStateObject[0]]; temp: ARRAY [0..minSize) OF WORD; cheat: POINTER TO BasicLoadStateFormat.LoadStateObject = LOOPHOLE[@temp]; WorldVM.CopyRead[world: world, to: @temp, from: basic, nwords: minSize]; IF world.basicLoadState = NIL OR cheat.length # world.basicLoadState.length THEN world.basicLoadState _ NEW[BasicLoadStateFormat.LoadStateObject[cheat.length]]; WorldVM.CopyRead[world: world, to: LOOPHOLE[world.basicLoadState,LONG POINTER], from: basic, nwords: SIZE[BasicLoadStateFormat.LoadStateObject[cheat.length]] ]; world.loadState _ ERROR -- to be implemented! --; END; END.