//-----------------------THREAD METHODS------------------------// /// <summary> /// Used to run program in background /// </summary> public void run() { shouldStop = false; Bus.Update_Bus(mainMemory[2], mainMemory[1], mainMemory[0], 16); while (!shouldStop && ((registers[2] & 0x2) != 0x2)) { //Fetch instruction instructionWorker.Fetch_Instruction(); Thread.Sleep(period); //Update message window and instruction windows SetText(currentInstruction, previousInstructionTextBox); SetText(nextInstruction, nextInstructionTextBox); if ((currentInstruction.Substring(0, 3) == "NOP") && (registers[1] == 1000)) { shouldStop = true; } if (printMessagesCheckBox.Checked) { Update_Messages(); } if (updateFormsCheckBox.Checked) { //Update the forms that are currently open if (ioPortsForm != null) { ioPortsForm.Update_IO(); } if (registerForm != null) { registerForm.Update_Registers(); } if (busForm != null) { busForm.Update_View(); } } } }
/// <summary> /// Processes a falling/rising edge of read or write from the CPU bus. Simulates the IDE interface hardware /// </summary> public void edgeDetector(bool read, bool write, bool CS, int dataIn) { int data = 0; //If it is a falling edge if (!read && !write) { if (CS == false) { //While peripheral not selected, keep state at 2 state = 1; DIOR = true; DIOW = true; } switch (state) { case 2: interfaceRegisters[0] = dataIn; break; case 3: interfaceRegisters[1] = dataIn; break; case 4: interfaceRegisters[2] = dataIn; break; case 5: interfaceRegisters[3] = dataIn; break; case 6: interfaceRegisters[4] = dataIn; break; case 7: if (!DIOW) //Writing to a hard drive register; { data = (interfaceRegisters[1] << 12) | (interfaceRegisters[2] << 8) | (interfaceRegisters[3] << 4) | interfaceRegisters[4]; //if the register being written to is the status register, don't overwrite it, just update values based on command if (interfaceRegisters[0] == 0xF) { data &= 0xFF; if ((data == 0x0030) || (data == 0x0020)) { //This is a hard drive write/read command hdRegisters[0xF] |= 0x8; dataLeft = 256 * (hdRegisters[0xA] & 0xFF); //There are 512 bytes of data in each sector, reg A is how many registers to transfer, each transfer dataLeft--; //sends 2 bytes at a time, therefore 256 transfers required per sector } } //A write to a sector has been started based on the 0x8 bit in status being on, and the data register is selected else if (((hdRegisters[0xF] & 0x8) == 0x8) && (interfaceRegisters[0] == 0x8)) //Data is being written to a sector { hdRegisters[interfaceRegisters[0]] = data; AccessHD(dataLeft, true); dataLeft--; //If all the data has been transfered to the sector, update the data ready flag in status if (dataLeft == -1) { hdRegisters[0xF] &= 0x00F0; hdRegisters[0xA]--; } } else { // Update the register that is requested with the data sent hdRegisters[interfaceRegisters[0]] = data; } } break; case 8: break; case 9: break; case 10: DIOR = true; DIOW = true; break; default: break; } state++; } else //Rising edge { //State 7 is when the transfer actually happens, update the DIOR/DIOW to initiate transfer with hard drive if (state == 7) { DIOR = !read; DIOW = !write; if (!DIOR) { if (((hdRegisters[0xF] & 0x8) == 0x8) && (interfaceRegisters[0] == 0x8)) //Data is being read from a sector { AccessHD(dataLeft, false); dataLeft--; //If all the data has been transfered, turn off the data ready flag if (dataLeft == -1) { hdRegisters[0xF] &= 0x00F0; hdRegisters[0xA]--; } } Bus.Update_Bus((hdRegisters[interfaceRegisters[0]] & 0xF000) >> 12, Bus.Get_Values()[1], Bus.Get_Values()[0], id); } } else if (state == 8) { if (!DIOR) { Bus.Update_Bus((hdRegisters[interfaceRegisters[0]] & 0x0F00) >> 8, Bus.Get_Values()[1], Bus.Get_Values()[0], id); //Send the next 4 bits of data from the hard drive back to CPU } } else if (state == 9) { if (!DIOR) { Bus.Update_Bus((hdRegisters[interfaceRegisters[0]] & 0x00F0) >> 4, Bus.Get_Values()[1], Bus.Get_Values()[0], id); //Send the next 4 bits of data from the hard drive back to CPU } } else if (state == 10) { if (!DIOR) { Bus.Update_Bus((hdRegisters[interfaceRegisters[0]] & 0x000F), Bus.Get_Values()[1], Bus.Get_Values()[0], id); //Send the next 4 bits of data from the hard drive back to CPU } state = 1; } } Update_View(hdRegisterListView); Update_View(interfaceRegisterListView); SetText(state.ToString(), hardDriveStateTextBox); }
public void Decode_Instruction(String inst, int address) { switch (inst) { case "HLT": registers[2] |= 0x2; break; case "LOD": if (registers[1] == 2) { registers[0] = (Bus.Get_Values())[0]; } else { registers[0] = mainMemory[registers[1]]; } break; case "STR": if (registers[1] == 1) { mainMemory[registers[1]] &= 0x3; mainMemory[registers[1]] = (UInt16)(((UInt16)registers[0] & 0xC) | mainMemory[registers[1]]); } else { mainMemory[registers[1]] = (UInt16)registers[0]; } if (registers[1] < 3) { Bus.Update_Bus(mainMemory[2], mainMemory[1], mainMemory[0], 16); } break; case "ADD": int temp1 = registers[0]; int temp2 = mainMemory[registers[1]]; int result = temp1 + temp2; result += (registers[2] & 0x1); registers[0] = result & 0xF; //Set overflow bit if (((temp1 & 0x8) == 0x8) && ((temp2 & 0x8) == 0x8) && ((result & 0x8) != 0x8)) { registers[2] |= 0x8; registers[2] ^= (result & 0x8); } else if (((temp1 & 0x8) != 0x8) && ((temp2 & 0x8) != 0x8) && ((result & 0x8) == 0x8)) { registers[2] |= 0x8; registers[2] ^= (result & 0x8); } else { registers[2] &= 0x7; registers[2] ^= (result & 0x8); } //If there was a carry out if ((result & 0x10) == 0x10) { registers[2] |= 0x1; } else { registers[2] &= 0xE; } break; case "NOP": break; case "NND": registers[0] &= mainMemory[registers[1]]; registers[0] = ~registers[0]; registers[0] &= 0xF; break; case "JMP": if (registers[0] == 0) { registers[3] = registers[1]; } break; case "CXA": registers[0] = registers[2]; break; default: registers[2] |= 0x2; break; } }