diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java index 10bfc1e2..ea1f47e5 100644 --- a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java +++ b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java @@ -36,8 +36,9 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual /////////////////////////////////////////////////////////////////// - private static final long ITEM_DEVICE_BASE_ADDRESS = 0x40000000L; + private static final long ITEM_DEVICE_BASE_ADDRESS = 0x20000000L; private static final int ITEM_DEVICE_STRIDE = 0x1000; + private static final long OTHER_DEVICE_BASE_ADDRESS = 0x30000000L; /////////////////////////////////////////////////////////////////// @@ -83,18 +84,18 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual final DeviceType deviceType = entry.getKey(); final DeviceItemStackHandler handler = entry.getValue(); - // Ahhh, such special casing, much wow. Honestly I don't expect this - // special case to ever be needed for anything other than physical - // memory, so it's fine. Prove me wrong. - if (deviceType == DeviceTypes.MEMORY) { - continue; - } - for (int i = 0; i < handler.getSlots(); i++) { final Collection devices = handler.getBusElement().getDeviceGroup(i); for (final ItemDeviceInfo info : devices) { if (Objects.equals(info.device, wrapper)) { - return OptionalLong.of(address); + // Ahhh, such special casing, much wow. Honestly I don't expect this + // special case to ever be needed for anything other than physical + // memory, so it's fine. Prove me wrong. + if (deviceType == DeviceTypes.MEMORY) { + return OptionalLong.empty(); + } else { + return OptionalLong.of(address); + } } } } @@ -102,7 +103,7 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual address += ITEM_DEVICE_STRIDE; } - return OptionalLong.empty(); + return OptionalLong.of(OTHER_DEVICE_BASE_ADDRESS); } @Override diff --git a/src/main/java/li/cil/oc2/common/vm/ManagedMemoryRangeAllocator.java b/src/main/java/li/cil/oc2/common/vm/ManagedMemoryRangeAllocator.java index a0e25064..5864d381 100644 --- a/src/main/java/li/cil/oc2/common/vm/ManagedMemoryRangeAllocator.java +++ b/src/main/java/li/cil/oc2/common/vm/ManagedMemoryRangeAllocator.java @@ -56,20 +56,26 @@ public final class ManagedMemoryRangeAllocator implements MemoryRangeAllocator { throw new IllegalStateException(); } - final OptionalLong address = defaultAddress.apply(device); - if (address.isPresent() && board.addDevice(address.getAsLong(), device)) { + OptionalLong address = defaultAddress.apply(device); + if (address.isPresent()) { + if (board.addDevice(address.getAsLong(), device)) { + managedDevices.add(device); + return address; + } + + address = board.getMemoryMap().findFreeRange(address.orElse(0), Long.MAX_VALUE, device.getLength()); + if (address.isPresent() && board.addDevice(address.getAsLong(), device)) { + managedDevices.add(device); + return address; + } + } + + if (board.addDevice(device)) { managedDevices.add(device); - return OptionalLong.of(address.getAsLong()); + final Optional range = board.getMemoryMap().getMemoryRange(device); + return OptionalLong.of(range.orElseThrow(AssertionError::new).address()); } - if (!board.addDevice(device)) { - return OptionalLong.empty(); - } - - final Optional range = board.getMemoryMap().getMemoryRange(device); - assert range.isPresent(); - - managedDevices.add(device); - return OptionalLong.of(range.get().address()); + return OptionalLong.empty(); } }