mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-19 12:17:17 -04:00
Added eeprom.getData/setData for mutable persistent bios storage, replaces get/setBootAddress.
get/setData is wrapped by the default Lua bios into functions with these names to avoid breaking programs using them.
This commit is contained in:
parent
9e92ee508c
commit
2ac78463a1
@ -36,20 +36,6 @@ public interface Machine extends ManagedEnvironment, Context {
|
|||||||
*/
|
*/
|
||||||
Architecture architecture();
|
Architecture architecture();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the address of the file system component from which to try to boot.
|
|
||||||
* <p/>
|
|
||||||
* The underlying architecture may choose to ignore this setting.
|
|
||||||
*/
|
|
||||||
String getBootAddress();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the address of the file system component from which to try to boot.
|
|
||||||
*
|
|
||||||
* @param value the new address to try to boot from.
|
|
||||||
*/
|
|
||||||
void setBootAddress(String value);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of components attached to this machine.
|
* The list of components attached to this machine.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -146,6 +146,9 @@ opencomputers {
|
|||||||
# The maximum size of the byte array that can be stored on EEPROMs.
|
# The maximum size of the byte array that can be stored on EEPROMs.
|
||||||
eepromSize: 4096
|
eepromSize: 4096
|
||||||
|
|
||||||
|
# The maximum size of the byte array that can be stored on EEPROMs.
|
||||||
|
eepromDataSize: 256
|
||||||
|
|
||||||
# The number of components the different CPU tiers support. This list
|
# The number of components the different CPU tiers support. This list
|
||||||
# must contain exactly three entries, or it will be ignored.
|
# must contain exactly three entries, or it will be ignored.
|
||||||
cpuComponentCount: [
|
cpuComponentCount: [
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
|
local component_invoke = component.invoke
|
||||||
function boot_invoke(address, method, ...)
|
function boot_invoke(address, method, ...)
|
||||||
local result = table.pack(pcall(component.invoke, address, method, ...))
|
local result = table.pack(pcall(component_invoke, address, method, ...))
|
||||||
if not result[1] then
|
if not result[1] then
|
||||||
return nil, result[2]
|
return nil, result[2]
|
||||||
else
|
else
|
||||||
return table.unpack(result, 2, result.n)
|
return table.unpack(result, 2, result.n)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- backwards compatibility, may remove later
|
||||||
|
local eeprom = component.list("eeprom")()
|
||||||
|
computer.getBootAddress = function()
|
||||||
|
return boot_invoke(eeprom, "getData")
|
||||||
|
end
|
||||||
|
computer.setBootAddress = function(address)
|
||||||
|
return boot_invoke(eeprom, "setData", address)
|
||||||
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
local screen = component.list("screen")()
|
local screen = component.list("screen")()
|
||||||
local gpu = component.list("gpu")()
|
local gpu = component.list("gpu")()
|
||||||
@ -27,7 +38,7 @@ local function tryLoadFrom(address)
|
|||||||
buffer = buffer .. (data or "")
|
buffer = buffer .. (data or "")
|
||||||
until not data
|
until not data
|
||||||
boot_invoke(address, "close", handle)
|
boot_invoke(address, "close", handle)
|
||||||
return load(buffer, "=init", "t", sandbox)
|
return load(buffer, "=init")
|
||||||
end
|
end
|
||||||
local init, reason
|
local init, reason
|
||||||
if computer.getBootAddress() then
|
if computer.getBootAddress() then
|
||||||
|
@ -58,6 +58,7 @@ class Settings(val config: Config) {
|
|||||||
val timeout = config.getDouble("computer.timeout") max 0
|
val timeout = config.getDouble("computer.timeout") max 0
|
||||||
val startupDelay = config.getDouble("computer.startupDelay") max 0.05
|
val startupDelay = config.getDouble("computer.startupDelay") max 0.05
|
||||||
val eepromSize = config.getInt("computer.eepromSize") max 0
|
val eepromSize = config.getInt("computer.eepromSize") max 0
|
||||||
|
val eepromDataSize = config.getInt("computer.eepromDataSize") max 0
|
||||||
val cpuComponentSupport = Array(config.getIntList("computer.cpuComponentCount"): _*) match {
|
val cpuComponentSupport = Array(config.getIntList("computer.cpuComponentCount"): _*) match {
|
||||||
case Array(tier1, tier2, tier3) =>
|
case Array(tier1, tier2, tier3) =>
|
||||||
Array(tier1: Int, tier2: Int, tier3: Int)
|
Array(tier1: Int, tier2: Int, tier3: Int)
|
||||||
|
@ -16,18 +16,20 @@ class EEPROM extends prefab.ManagedEnvironment {
|
|||||||
withConnector().
|
withConnector().
|
||||||
create()
|
create()
|
||||||
|
|
||||||
var data = Array.empty[Byte]
|
var codeData = Array.empty[Byte]
|
||||||
|
|
||||||
|
var volatileData = Array.empty[Byte]
|
||||||
|
|
||||||
var readonly = false
|
var readonly = false
|
||||||
|
|
||||||
var label = "EEPROM"
|
var label = "EEPROM"
|
||||||
|
|
||||||
def checksum = Hashing.crc32().hashBytes(data).toString
|
def checksum = Hashing.crc32().hashBytes(codeData).toString
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@Callback(direct = true, doc = """function():string -- Get the currently stored byte array.""")
|
@Callback(direct = true, doc = """function():string -- Get the currently stored byte array.""")
|
||||||
def get(context: Context, args: Arguments): Array[AnyRef] = result(data)
|
def get(context: Context, args: Arguments): Array[AnyRef] = result(codeData)
|
||||||
|
|
||||||
@Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""")
|
@Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""")
|
||||||
def set(context: Context, args: Arguments): Array[AnyRef] = {
|
def set(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
@ -37,9 +39,9 @@ class EEPROM extends prefab.ManagedEnvironment {
|
|||||||
if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) {
|
if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) {
|
||||||
return result(Unit, "not enough energy")
|
return result(Unit, "not enough energy")
|
||||||
}
|
}
|
||||||
val newData = args.checkByteArray(0)
|
val newData = args.optByteArray(0, Array.empty)
|
||||||
if (newData.length > Settings.get.eepromSize) throw new IllegalArgumentException("not enough space")
|
if (newData.length > Settings.get.eepromSize) throw new IllegalArgumentException("not enough space")
|
||||||
data = newData
|
codeData = newData
|
||||||
context.pause(2) // deliberately slow to discourage use as normal storage medium
|
context.pause(2) // deliberately slow to discourage use as normal storage medium
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -72,21 +74,41 @@ class EEPROM extends prefab.ManagedEnvironment {
|
|||||||
else result(Unit, "incorrect checksum")
|
else result(Unit, "incorrect checksum")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Callback(direct = true, doc = """function():string -- Get the storage capacity of this EEPROM.""")
|
||||||
|
def getDataSize(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.eepromDataSize)
|
||||||
|
|
||||||
|
@Callback(direct = true, doc = """function():string -- Get the currently stored byte array.""")
|
||||||
|
def getData(context: Context, args: Arguments): Array[AnyRef] = result(volatileData)
|
||||||
|
|
||||||
|
@Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""")
|
||||||
|
def setData(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
|
if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) {
|
||||||
|
return result(Unit, "not enough energy")
|
||||||
|
}
|
||||||
|
val newData = args.optByteArray(0, Array.empty)
|
||||||
|
if (newData.length > Settings.get.eepromDataSize) throw new IllegalArgumentException("not enough space")
|
||||||
|
volatileData = newData
|
||||||
|
context.pause(1) // deliberately slow to discourage use as normal storage medium
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
override def load(nbt: NBTTagCompound) {
|
override def load(nbt: NBTTagCompound) {
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
data = nbt.getByteArray(Settings.namespace + "eeprom")
|
codeData = nbt.getByteArray(Settings.namespace + "eeprom")
|
||||||
if (nbt.hasKey(Settings.namespace + "label")) {
|
if (nbt.hasKey(Settings.namespace + "label")) {
|
||||||
label = nbt.getString(Settings.namespace + "label")
|
label = nbt.getString(Settings.namespace + "label")
|
||||||
}
|
}
|
||||||
readonly = nbt.getBoolean(Settings.namespace + "readonly")
|
readonly = nbt.getBoolean(Settings.namespace + "readonly")
|
||||||
|
volatileData = nbt.getByteArray(Settings.namespace + "userdata")
|
||||||
}
|
}
|
||||||
|
|
||||||
override def save(nbt: NBTTagCompound) {
|
override def save(nbt: NBTTagCompound) {
|
||||||
super.save(nbt)
|
super.save(nbt)
|
||||||
nbt.setByteArray(Settings.namespace + "eeprom", data)
|
nbt.setByteArray(Settings.namespace + "eeprom", codeData)
|
||||||
nbt.setString(Settings.namespace + "label", label)
|
nbt.setString(Settings.namespace + "label", label)
|
||||||
nbt.setBoolean(Settings.namespace + "readonly", readonly)
|
nbt.setBoolean(Settings.namespace + "readonly", readonly)
|
||||||
|
nbt.setByteArray(Settings.namespace + "userdata", volatileData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
|
|
||||||
var architecture: Architecture = _
|
var architecture: Architecture = _
|
||||||
|
|
||||||
private var bootAddress = ""
|
|
||||||
|
|
||||||
private[machine] val state = mutable.Stack(Machine.State.Stopped)
|
private[machine] val state = mutable.Stack(Machine.State.Stopped)
|
||||||
|
|
||||||
private val _components = mutable.Map.empty[String, String]
|
private val _components = mutable.Map.empty[String, String]
|
||||||
@ -142,10 +140,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
hasMemory = Option(architecture).fold(false)(_.recomputeMemory(components))
|
hasMemory = Option(architecture).fold(false)(_.recomputeMemory(components))
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getBootAddress = bootAddress
|
|
||||||
|
|
||||||
override def setBootAddress(value: String) = bootAddress = Option(value).fold("")(_.take(36))
|
|
||||||
|
|
||||||
override def components = scala.collection.convert.WrapAsJava.mapAsJavaMap(_components)
|
override def components = scala.collection.convert.WrapAsJava.mapAsJavaMap(_components)
|
||||||
|
|
||||||
def componentCount = (_components.foldLeft(0.0)((acc, entry) => entry match {
|
def componentCount = (_components.foldLeft(0.0)((acc, entry) => entry match {
|
||||||
@ -649,8 +643,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
|
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
|
|
||||||
bootAddress = nbt.getString("bootAddress")
|
|
||||||
|
|
||||||
state.pushAll(nbt.getIntArray("state").reverse.map(Machine.State(_)))
|
state.pushAll(nbt.getIntArray("state").reverse.map(Machine.State(_)))
|
||||||
nbt.getTagList("users", NBT.TAG_STRING).foreach((tag: NBTTagString) => _users += tag.func_150285_a_())
|
nbt.getTagList("users", NBT.TAG_STRING).foreach((tag: NBTTagString) => _users += tag.func_150285_a_())
|
||||||
if (nbt.hasKey("message")) {
|
if (nbt.hasKey("message")) {
|
||||||
@ -718,10 +710,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
|
|
||||||
super.save(nbt)
|
super.save(nbt)
|
||||||
|
|
||||||
if (bootAddress != null) {
|
|
||||||
nbt.setString("bootAddress", bootAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the component list is up-to-date.
|
// Make sure the component list is up-to-date.
|
||||||
processAddedComponents()
|
processAddedComponents()
|
||||||
|
|
||||||
|
@ -37,23 +37,6 @@ class ComputerAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
|||||||
})
|
})
|
||||||
lua.setField(-2, "address")
|
lua.setField(-2, "address")
|
||||||
|
|
||||||
// Get/set address of boot device.
|
|
||||||
lua.pushScalaFunction(lua => {
|
|
||||||
owner.machine.getBootAddress match {
|
|
||||||
case "" => lua.pushNil()
|
|
||||||
case address => lua.pushString(address)
|
|
||||||
}
|
|
||||||
1
|
|
||||||
})
|
|
||||||
lua.setField(-2, "getBootAddress")
|
|
||||||
|
|
||||||
lua.pushScalaFunction(lua => {
|
|
||||||
if (lua.isNoneOrNil(1)) owner.machine.setBootAddress("")
|
|
||||||
else owner.machine.setBootAddress(lua.checkString(1).take(36))
|
|
||||||
0
|
|
||||||
})
|
|
||||||
lua.setField(-2, "setBootAddress")
|
|
||||||
|
|
||||||
lua.pushScalaFunction(lua => {
|
lua.pushScalaFunction(lua => {
|
||||||
// This is *very* unlikely, but still: avoid this getting larger than
|
// This is *very* unlikely, but still: avoid this getting larger than
|
||||||
// what we report as the total memory.
|
// what we report as the total memory.
|
||||||
|
@ -27,18 +27,6 @@ class ComputerAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
|
|||||||
case _ => LuaValue.NIL
|
case _ => LuaValue.NIL
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get/set address of boot device.
|
|
||||||
computer.set("getBootAddress", (_: Varargs) => owner.machine.getBootAddress match {
|
|
||||||
case "" => LuaValue.NIL
|
|
||||||
case address => LuaValue.valueOf(address)
|
|
||||||
})
|
|
||||||
|
|
||||||
computer.set("setBootAddress", (args: Varargs) => {
|
|
||||||
if (args.isnoneornil(1)) owner.machine.setBootAddress("")
|
|
||||||
else owner.machine.setBootAddress(args.checkjstring(1).take(36))
|
|
||||||
LuaValue.NIL
|
|
||||||
})
|
|
||||||
|
|
||||||
computer.set("freeMemory", (_: Varargs) => LuaValue.valueOf(owner.memory / 2))
|
computer.set("freeMemory", (_: Varargs) => LuaValue.valueOf(owner.memory / 2))
|
||||||
|
|
||||||
computer.set("totalMemory", (_: Varargs) => LuaValue.valueOf(owner.memory))
|
computer.set("totalMemory", (_: Varargs) => LuaValue.valueOf(owner.memory))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user