public boolean disassemble(Program program, Instruction instr, TaskMonitor monitor) {
		// disassemble the table
		// pull out the current context so we can flow anything that needs to flow
		ProgramContext programContext = program.getProgramContext();
		Register baseContextRegister = programContext.getBaseContextRegister();
		RegisterValue switchContext = null;
		if (baseContextRegister != null) {
			// Use disassembler context based upon context register value from switch location
			switchContext =
				programContext.getRegisterValue(baseContextRegister, instr.getMinAddress());
		}

		Listing listing = program.getListing();
		boolean gotNewCode = false;
		for (Address tableElement : tableElements) {
			Address caseStart = tableElement;

			// if conflict skip case
			if (listing.getUndefinedDataAt(caseStart) == null) {
				continue;
			}
			if (switchContext != null) {
				try {
					// Use disassembler context based upon context register value from function entry point
					RegisterValue curContext =
						programContext.getRegisterValue(baseContextRegister, caseStart);
					if (curContext != null) {
						curContext = curContext.combineValues(switchContext);

						// lay down the new merged context
						programContext.setRegisterValue(caseStart, caseStart, curContext);
					}
					else {
						programContext.setRegisterValue(caseStart, caseStart, switchContext);
					}
				}
				catch (ContextChangeException e) {
					// This can occur when two or more threads are working on the same function
					continue;
				}
			}

			gotNewCode |= !disassembleTarget(program, caseStart, monitor).isEmpty();
		}

		return gotNewCode;
	}
Disassemble all the entries in the table
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/AddressTable.java