Beispiel #1
0
Error rntFlyExec(char *cmd)
{
	MemCell		memcell,
			value;
	Error		rval;
	unsigned int	address;
	char		buff[101];

	rval = parseAsmInstr(cmd, &memcell);
	if(rval != ERR_None)
	{
		consoleOut("Error parsing asm instruction\n");
		return rval;
	}

	rval = executeInstr(memcell.instructie, 1);
	if(rval != ERR_None)
	{
		consoleOut("Error executing asm instruction\n");
	}

	if(memoryChanged(&address, &value) != ERR_InvalidState)
	{
		sprintf(buff, "  [Memory] %010u:\t%d\n", address, value.getal);
		consoleOut(buff);
	}
	rntDisplayStatus();

	return ERR_None;
}
Beispiel #2
0
    void Monitor::procMemory() {
        unsigned long free = 0;
        MemoryHandler handler(fTotalMemory, free);

        QString path = QStringLiteral("/proc/meminfo");
        if ( fProcReader.readProcFile(path, handler, 4, -1) == 0 ) {
            emit memoryChanged(fTotalMemory, free);
        }
    }
Beispiel #3
0
Error rntFlyAsm(unsigned int address, char *cmd)
{
	MemCell		memcell,
			value;
	Error		rval;
	char		buff[111];

	rval = parseAsmInstr(cmd, &memcell);
	if(rval != ERR_None)
	{
		consoleOut("Error parsing asm instruction\n");
		return rval;
	}

	rval = writeMemory(address, memcell);
	if(rval != ERR_None)
	{
		consoleOut("Error writing to memory\n");
		return rval;
	}
	else
	{
		ProcInfo info;

		if(memoryChanged(&address, &value) != ERR_InvalidState)
		{
			sprintf(buff, "  [Memory] %010u:\t%d (%s)\n", address, value.getal, cmd);
			consoleOut(buff);
		}

		// Next instruction could have changed
		info = getStatus();
		if(info.progCounter == address)
		{
			rntDisplayStatus();
		}
	}

	return ERR_None;
}
Beispiel #4
0
/** Step the next instruction
 *
 * See executeNextInstr for possible error codes
 */
Error rntStep(void)
{
	Error		rval = ERR_None;
	MemCell		value;
	unsigned int	address;
	char		buff[101];

	rval = executeNextInstr();
	if(rval != ERR_None && rval != ERR_Breakpoint)
	{
		displayError(rval);
		return rval;
	}

	if(memoryChanged(&address, &value) != ERR_InvalidState)
	{
		sprintf(buff, "  [Memory] %010u:\t%d\n", address, value.getal);
		consoleOut(buff);
	}

	rntDisplayStatus();

	return ERR_None;
}
Beispiel #5
0
bool Compiler::compile(QStringList *msgs)
{
	if(!precompile(msgs))
		return false;

	QList<int> words;
	QList<LabelItem> labelQueue;
	int address = 0;

	auto packValue = [&](const int &value)
	{
		if(words.isEmpty())
			return;

		words.last() += value;
	};

	auto packOperand = [&](const int &operand)
	{
		if(words.isEmpty())
			return;

		words.last() += operand * 10000;
	};

	auto parseOperand = [&](QString operand, const int &n, const int &line)
	{
		operand.replace('\t', "").replace('\n', "");

		bool isPointer = false;
		if((operand[0] == '[') && (operand[operand.length() - 1] == ']')) {
			isPointer = true;
			operand = operand.mid(1, operand.length() - 2);
		}

		bool isConst = false;
		if(!isPointer && operand.startsWith('$')) {
			isConst = true;
			operand = operand.mid(1);
		}

		bool isNumber = false;
		operand.toInt(&isNumber);

		if((operand[0] == '"') && (operand[operand.length() - 1] == '"')) {
			//string literal
			operand = operand.mid(1, operand.length() - 2);

			words.clear();

			for(int i = 0; i < operand.length(); ++i) {
				char c = operand[i].toLatin1();

				if(c == '\\') {
					switch(operand[i + 1].toLatin1()) {
						case 'n':  c = 10; break;
						case 'r':  c = 13; break;
						case 'a':  c = 7;  break;
						case '\\': c = 92; break;
						case '"':  c = 34; break;
						case '0':  c = 0;  break;

						default:
						{
							if(msgs) *msgs << tr("%1:Unrecognised string escape \\%2").arg(line).arg(operand[i+1]);

							return false;
						}
					}

					++i;
				}

				words << c;
			}
		} else if(isPointer && (operand.split('+').size() == 2)) {
			//register + offset
			const QString errorStr = tr("%1:Invalid offset pointer, must be one literal/label and one register");

			const QStringList split = operand.replace(' ', "").split('+');
			QString reg;
			QString offset;

			for(int i = 0; i < 2; ++i) {
				bool isOffset = false;
				int number = split[i].toInt(&isOffset);

				if(isOffset) {
					if(offset.isEmpty()) {
						offset = QString::number(number);
					} else {
						if(msgs) *msgs << errorStr.arg(line);

						return false;
					}

					packValue(number);
				} else if(registerList.contains(split[i].toUpper())) {
					if(reg.isEmpty()) {
						reg = split[i].toUpper();
					} else {
						if(msgs) *msgs << errorStr.arg(line);

						return false;
					}
				} else if(offset.isEmpty() && labelPattern.match(split[i]).hasMatch()) {
					LabelItem label;
					label.name = split[i];
					label.address = address;
					labelQueue << label;
				} else {
					if(msgs) *msgs << errorStr.arg(line);

					return false;
				}
			}

			if(reg == "AX") {
				packOperand(8);
			} else if(reg == "IP") {
				packOperand(9);
			} else if(reg == "SP") {
				packOperand(10);
			} else if(reg == "SB") {
				packOperand(11);
			} else if(reg == "DI") {
				packOperand(12);
			}
		} else if(isNumber) {
			const int value = operand.toInt();

			const int intValue = VirtualMachine::memoryToInt(value);
			if((intValue < -999) || (intValue > 999)) {
				if(msgs) *msgs << tr("%1:Value out of range \"%2\"").arg(line).arg(value);
				return false;
			}

			if(n > 0)
				words << 0;

			if(isPointer) {
				packOperand(1);
			} else if(isConst) {
				packOperand(2);
			} else {
				packOperand(0);
			}

			packValue(value);
		} else {
			if(registerList.contains(operand.toUpper())) {
				if(operand.toUpper() == "AX") {
					packOperand(isPointer ? 8 : 3);
				} else if(operand.toUpper() == "IP") {
					packOperand(isPointer ? 9 : 4);
				} else if(operand.toUpper() == "SP") {
					packOperand(isPointer ? 10 : 5);
				} else if(operand.toUpper() == "SB") {
					packOperand(isPointer ? 11 : 6);
				} else if(operand.toUpper() == "DI") {
					packOperand(isPointer ? 12 : 7);
				}
			} else {
				if(isPointer) {
					packOperand(1);
				} else if(isConst) {
					packOperand(2);
				} else {
					packOperand(0);
				}

				if(labelPattern.match(operand).hasMatch()) {
					LabelItem label;
					label.name = operand;
					label.address = address;
					labelQueue << label;
				} else {
					if(msgs) *msgs << tr("%1:Illegal symbol in label \"%2\"").arg(line).arg(operand);

					return false;
				}
			}
		}

		return true;
	};

	QHash<int, int> memory;

	for(int i = 0; i < m_instructions.size(); ++i) {
		const QString mnemonic = m_instructions[i].mnemonic.toUpper();
		const QStringList operands = m_instructions[i].operands;

		if((mnemonic == ".CODE") || (mnemonic == ".DATA")) {
			if(operands.size()) {
				address = operands[0].toInt();

				if((mnemonic == ".CODE") && (m_startCell == -1)) {
					m_startCell = address;
				}
			}
		} else {
			if(mnemonicMap.value(mnemonic).operands > operands.size()) {
				if(msgs) *msgs << tr("%1:Invalid operand count for \"%2\" (expecting %3)").arg(m_instructionMap[i])
																						  .arg(mnemonic)
																						  .arg(mnemonicMap.value(mnemonic).operands);

				return false;
			}

			if(mnemonicMap.value(mnemonic.toUpper()).code > -1) {
				words = { mnemonicMap.value(mnemonic.toUpper()).code * 1000000 };
			} else {
				words = { 0 };
			}

			for(int j = 0; j < operands.size(); ++j) {
				if(!parseOperand(operands[j], j, m_instructionMap[i]))
					return false;
			}

			const int prevAddress = address;
			for(int j = 0; j < words.size(); ++j)
				memory.insert(address++, words[j]);

			for(int j = prevAddress; j <= address; ++j) {
				if(!m_addressMap.values().contains(i))
					m_addressMap.insert(j, i);
			}
		}
	}

	for(int i = 0; i < labelQueue.size(); ++i) {
		if(!m_labelMap.contains(labelQueue[i].name)) {
			if(msgs) *msgs << tr("%1:Undefined label \"%2\"").arg(-1).arg(labelQueue[i].name);

			return false;
		}

		int value = address;
		const int key = m_addressMap.key(m_labelMap.value(labelQueue[i].name), -1);
		if(key > -1)
			value = key;

		memory[labelQueue[i].address] += value;
	}

	QHashIterator<int, int> it(memory);
	while(it.hasNext()) {
		it.next();

		emit memoryChanged(it.key(), it.value());
	}

	return true;
}