private void doInstr(byte command, uint target, out CPUBasic.eCPUErrors err) { err = eCPUError.NONE; bool isMemLocation = (CPUBasic.FLAG_MEM_OR_NUM & target) > 0; bool isJump = (CPUBasic.FLAG_JUMP_ADDRESS & target) > 0; bool isBitAccess = (CPUBasic.FLAG_BIT_ACCESS & target) > 0; uint len = (CPUBasic.FLAG_BITFIELD_VAL & target) >> 20; eMemRange witchMem = (CPUBasic.FLAG_MEM_MARKER & target) > 0 ? eMemRange.MARKER : eMemRange.NONE; witchMem = (CPUBasic.FLAG_MEM_OUTPUT & target) > 0 ? eMemRange.OUTPUT : witchMem; witchMem = (CPUBasic.FLAG_MEM_INPUT & target) > 0 ? eMemRange.INPUT : witchMem; if (isJump && witchMem != eMemRange.NONE) err = eCPUError.JUMP_AND_MEMORY; if (isMemLocation && isBitAccess && len > 15 || isMemLocation && isBitAccess && len < 0) err = eCPUError.BIT_OUT_OF_RANGE; if (isMemLocation && !isJump && !isBitAccess && len > 4 || isMemLocation && !isJump && !isBitAccess && len < 1) err = eCPUError.MEM_LEN_OUT_OF_RANGE; if (isBitAccess && isJump) err = eCPUError.JUMP_AND_BITACCESS; if (err != eCPUError.NONE) return; int value = 0; if (isMemLocation) value = (int)(CPUBasic.FLAG_MEMADR & target); else value = (int)(CPUBasic.FLAG_CONSTVAL & target); eCPUCommands cmd = (eCPUCommands)command; switch (cmd) { case eCPUCommands.L: m_iAkku1 = getValue(isMemLocation, isBitAccess, witchMem, value, (int)len); break; case eCPUCommands.T: setValue(isBitAccess, witchMem, value, (int)len, m_iAkku1); break; case eCPUCommands.LN: if (isBitAccess) { m_iAkku1 = 1 - getValue(isMemLocation, isBitAccess, witchMem, value, (int)len); } break; case eCPUCommands.R: if (isBitAccess && m_iAkku1 == 1) { setValue(isBitAccess, witchMem, value, (int)len, 0); } break; case eCPUCommands.S: if (isBitAccess && m_iAkku1 == 1) { setValue(isBitAccess, witchMem, value, (int)len, 1); } break; case eCPUCommands.E: if (isBitAccess) { setValue(isBitAccess, witchMem, value, (int)len, m_iAkku1); } break; case eCPUCommands.EN: if (isBitAccess) { setValue(isBitAccess, witchMem, value, (int)len, 1 - m_iAkku1); } break; case eCPUCommands.A: if (isBitAccess) { m_iAkku2 = m_iAkku1; m_iAkku1 = getValue(isMemLocation, isBitAccess, witchMem, value, (int)len); m_iAkku1 = m_iAkku1 & m_iAkku2; } break; case eCPUCommands.O: if (isBitAccess) { m_iAkku2 = m_iAkku1; m_iAkku1 = getValue(isMemLocation, isBitAccess, witchMem, value, (int)len); m_iAkku1 = m_iAkku1 | m_iAkku2; } break; case eCPUCommands.AN: if (isBitAccess) { m_iAkku2 = m_iAkku1; m_iAkku1 = 1 - getValue(isMemLocation, isBitAccess, witchMem, value, (int)len); m_iAkku1 = m_iAkku1 & m_iAkku2; } break; case eCPUCommands.ON: if (isBitAccess) { m_iAkku2 = m_iAkku1; m_iAkku1 = 1 - getValue(isMemLocation, isBitAccess, witchMem, value, (int)len); m_iAkku1 = m_iAkku1 | m_iAkku2; } break; case eCPUCommands.XOR: if (isBitAccess) { m_iAkku2 = m_iAkku1; m_iAkku1 = 1 - getValue(isMemLocation, isBitAccess, witchMem, value, (int)len); m_iAkku1 = m_iAkku1 ^ m_iAkku2; } break; case eCPUCommands.JA: if (isJump) { if (len == 1) { m_iLoopInstrAddress = value * CPUBasic.INSTR_SIZE + (m_iInstrBase); m_iInstrPointer = m_byaInstrMemory.Length - 1; m_bLoop = true; break; } m_iInstrPointer = value * CPUBasic.INSTR_SIZE + (m_iInstrBase - CPUBasic.INSTR_SIZE); } break; case eCPUCommands.JC: if (isJump && m_iAkku1 == 1) { if (len == 1) { m_iLoopInstrAddress = value * CPUBasic.INSTR_SIZE + (m_iInstrBase); m_iInstrPointer = m_byaInstrMemory.Length - 1; m_bLoop = true; break; } m_iInstrPointer = value * CPUBasic.INSTR_SIZE + (m_iInstrBase - CPUBasic.INSTR_SIZE); } break; case eCPUCommands.JCN: if (isJump && m_iAkku1 == 0) { if (len == 1) { m_iLoopInstrAddress = value * CPUBasic.INSTR_SIZE + (m_iInstrBase); m_iInstrPointer = m_byaInstrMemory.Length - 1; m_bLoop = true; break; } m_iInstrPointer = value * CPUBasic.INSTR_SIZE + (m_iInstrBase - CPUBasic.INSTR_SIZE); } break; case eCPUCommands.SET: m_iAkku1 = 1; break; case eCPUCommands.NOP: // nothing to do empty command break; default: err = eCPUError.UNKOWN_CMD; break; } m_iInstrPointer += CPUBasic.INSTR_SIZE; }
private int getValueMem(bool isBit, CPUBasic.eMemRange range, int targetVal, int bitfield) { int akkuVal = 0; switch (range) { case CPUBasic.eMemRange.MARKER: if (isBit) { akkuVal = m_byaMarkerMemory[targetVal] & CPUBasic.BITVALUES[bitfield]; } else { for (int i = 0; i < bitfield; i++) { akkuVal |= m_byaMarkerMemory[targetVal + i] << (i * 8); } } break; case CPUBasic.eMemRange.OUTPUT: if (isBit) { akkuVal = m_byaOutputMemory[targetVal] & CPUBasic.BITVALUES[bitfield]; } else { for (int i = 0; i < bitfield; i++) { akkuVal |= m_byaOutputMemory[targetVal + i] << (i * 8); } } break; case CPUBasic.eMemRange.INPUT: if (isBit) { akkuVal = m_byaInputMemory[targetVal] & CPUBasic.BITVALUES[bitfield]; } else { for (int i = 0; i < bitfield; i++) { akkuVal |= m_byaInputMemory[targetVal + i] << (i * 8); } } break; } return akkuVal; }