private void BitPatternSTO(ushort operand, out ushort destAddress, out RegGeneral source)
{
// Decode the operand word's constituent bits. FEDC BA98 7654 3210
// SAAA rrrE OOOO ORRR
int addressingMode = (operand & 0x7000) >> 12;
RegGeneral addrRegister = (RegGeneral)((operand & 0x0E00) >> 9);
source = (RegGeneral)(operand & 0x0007); // R = source register
switch (addressingMode) // will always be between 0x0 and 0x7
{
case 0: // Immediate (r == 0), Absolute (r == 1), else Control Register
if (addrRegister == 0) {
// Immediate - no such addressing mode for STO.
source = RegGeneral.None;
destAddress = 0;
Interrupt_UndefFault(operand);
}
else if ((int)addrRegister == 1) {
destAddress = ReadMemInt16(PC, SegmentIndex.CS);
PC += 2; // advance PC two bytes because we're reading an immediate value.
}
else {
RegControl cr = (RegControl)((operand & 0x0700) >> 8);
WriteControlRegister(operand, cr, R[(int)source]);
// set source = none so calling function doesn't attempt to interpret this as well.
source = RegGeneral.None;
destAddress = 0;
}
break;
case 1: // Register - no such addressing mode for STO.
source = RegGeneral.None;
destAddress = 0;
Interrupt_UndefFault(operand);
break;
case 2: // Indirect
destAddress = R[(int)addrRegister];
break;
case 3: // Absolute Offset AKA Indirect Offset
destAddress = (ushort)(R[(int)addrRegister] + ReadMemInt16(PC, SegmentIndex.CS));
PC += 2; // advance PC two bytes because we're reading an immediate value.
break;
default: // $8-$F are Indirect Indexed operations.
int indexRegister = addressingMode; // bit pattern is 01ii, indicating r4 - r7.
destAddress = (ushort)(R[(int)source] + R[indexRegister]);
break;
}
}