InstructionBlock getNextBlockToBeDisassembled(Address fallThruAddr, Memory memory,
			TaskMonitor monitor) {

		if (monitor != null && monitor.isCancelled()) {
			lastBlock = null;
			return null;
		}

		if (fallThruAddr != null) {
			if (lastBlock == null) {
				throw new IllegalStateException();
			}
			// no state change fallThruAddr is 
			if (fallThruAddr.equals(lastBlockAddr)) {
				return lastBlock;
			}
			// fallthrough within block - continue disassembly of last block
			lastFlowFrom = lastBlockAddr;
			lastBlockAddr = fallThruAddr;

			if (checkMemoryRestriction(fallThruAddr)) {
				lastFlowFrom = lastBlockAddr;
				lastBlockAddr = fallThruAddr;
				return lastBlock;
			}
		}

		lastBlock = null;
		lastBlockAddr = null;
		lastFlowFrom = null;

		while ((monitor == null || !monitor.isCancelled()) &&
			(fallThruAddr != null || !priorityQueue.isEmpty() || !currentBranchQueue.isEmpty())) {

			// Prepare new block using next queued flow
			boolean forcedStartOfFlow = false;
			InstructionBlockFlow branchFlow = null;
			if (!priorityQueue.isEmpty()) {
				branchFlow = priorityQueue.first();
				priorityQueue.remove(branchFlow);
				// must force start of flow within InstructionSet so that this flow
				// is not dependent upon a flow-from block within the InstructionSet
				forcedStartOfFlow = true;
			}
			else if (!currentBranchQueue.isEmpty()) {
				branchFlow = currentBranchQueue.first();
				currentBranchQueue.remove(branchFlow);
			}
			processedBranchFlows.add(branchFlow);

			Address blockAddr = branchFlow.getDestinationAddress();
			if (blockAddr instanceof SegmentedAddress) {
				blockAddr = normalize((SegmentedAddress) blockAddr, memory);
			}

			if (checkMemoryRestriction(blockAddr)) {
				lastBlockAddr = blockAddr;
				lastFlowFrom = branchFlow.getFlowFromAddress();
				lastBlock = new InstructionBlock(lastBlockAddr);
				lastBlock.setFlowFromAddress(lastFlowFrom);
				lastBlock.setStartOfFlow(forcedStartOfFlow);
				break;
			}
		}
		return lastBlock;
	}
Return next block to disassemble for the current InstructionSet.
@param fallThruAddr specifies the next instruction to be disassembled if the 
previous instruction had a fall-through.  If specified, the previous block 
will be return.  If null, the next block to be disassembled will be returned. 
@param memory needed for normalization of SegementedAddresses (may be null).
@param monitor cancellable task monitor 
@return next block to be disassembled or null if no more queued flows to process
for current InstructionSet, or remaining flows fall outside restricted address set,
monitor has cancelled disassembly.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/DisassemblerQueue.java