//---------------------------------- THREADING METHODS------------------------------------//


        /// <summary>
        /// Basically attaches the hard drive to the bus and updates when needed
        /// </summary>
        public void run()
        {
            int [] prevValues = Bus.Get_Values();
            int[]  newValues;
            shouldStop = false;
            bool r, w, cs;

            while (!shouldStop)
            {
                newValues = Bus.Get_Values();
                if (newValues[1] != prevValues[1])
                {
                    if ((newValues[1] & 0x8) != 0)
                    {
                        r = true;
                    }
                    else
                    {
                        r = false;
                    }
                    if ((newValues[1] & 0x4) != 0)
                    {
                        w = true;
                    }
                    else
                    {
                        w = false;
                    }
                    if ((newValues[2]) == id)
                    {
                        cs = true;
                    }
                    else
                    {
                        cs = false;
                    }

                    //Thread.Sleep(1);
                    prevValues = newValues;
                    edgeDetector(r, w, cs, newValues[0]);
                }
            }
        }
Beispiel #2
0
 public void Update_View()
 {
     if (this.view.InvokeRequired)
     {
         UpdateViewCallback ca = new UpdateViewCallback(Update_View);
         this.Invoke(ca, new object[] {});
     }
     else
     {
         int[] values = Bus.Get_Values();
         view.Items.Clear();
         view.Items.Add("Chip Select");
         view.Items.Add("Status");
         view.Items.Add("Data");
         view.Items[0].SubItems.Add(values[2].ToString());
         view.Items[1].SubItems.Add(values[1].ToString());
         view.Items[2].SubItems.Add(values[0].ToString());
     }
 }
        /// <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);
        }
Beispiel #4
0
            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;
                }
            }