Example #1
0
        /// <summary>
        /// Starts this hardware device.
        /// </summary>
        public override void Start()
        {
            if (Device.Status != DeviceStatus.Available)
            {
                return;
            }

            // Disable all UART interrupts
            ierBase.Write8(0x00);

            // Enable DLAB (set baud rate divisor)
            lcrBase.Write8((byte)LCR.DLAB);

            // Set Baud rate
            const int baudRate = 115200;
            const int divisor  = 115200 / baudRate;

            dllBase.Write8((byte)(divisor & 0xFF));
            dlmBase.Write8((byte)(divisor >> 8 & 0xFF));

            // Reset DLAB, Set 8 bits, no parity, one stop bit
            lcrBase.Write8((byte)(LCR.CS8 | LCR.ST1 | LCR.PNO));

            // Enable FIFO, clear them, with 14-byte threshold
            fcrBase.Write8((byte)(FCR.Enabled | FCR.CLR_RCVR | FCR.CLR_XMIT | FCR.TL14));

            // IRQs enabled, RTS/DSR set
            mcrBase.Write8((byte)(MCR.DTR | MCR.RTS | MCR.OUT2));

            // Interrupt when data received
            ierBase.Write8((byte)IER.DR);

            Device.Status = DeviceStatus.Online;
        }
Example #2
0
        /// <summary>
        /// Write a value to the indexed sequence register.
        /// </summary>
        /// <param name="index">The index to the register</param>
        /// <param name="value">Value to write</param>
        private void WriteSequenceRegister(byte index, byte value)
        {
            // Select target register
            seqControllerIndex.Write8(index);

            // Write masked value to register
            seqControllerData.Write8(value);
        }
Example #3
0
 /// <summary>
 /// Sets the palette.
 /// </summary>
 /// <param name="colorIndex">Index of the color.</param>
 /// <param name="color">The color.</param>
 public void SetPalette(byte colorIndex, Color color)
 {
     dacPaletteMask.Write8(0xFF);
     dacIndexWrite.Write8(colorIndex);
     dacData.Write8(color.Red);
     dacData.Write8(color.Green);
     dacData.Write8(color.Blue);
 }
Example #4
0
        public override void Probe()
        {
            LBALowPort.Write8(0x88);

            var found = LBALowPort.Read8() == 0x88;

            Device.Status = (found) ? DeviceStatus.Available : DeviceStatus.NotFound;
        }
        /// <summary>
        /// Performs the LBA28.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="drive">The drive NBR.</param>
        /// <param name="lba">The lba.</param>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <returns></returns>
        protected bool PerformLBA28(SectorOperation operation, uint drive, uint lba, byte[] data, uint offset)
        {
            if (drive > MaximunDriveCount)
            {
                return(false);
            }

            FeaturePort.Write8(0);
            SectorCountPort.Write8(1);

            LBALowPort.Write8((byte)(lba & 0xFF));
            LBAMidPort.Write8((byte)((lba >> 8) & 0xFF));
            LBAHighPort.Write8((byte)((lba >> 16) & 0xFF));

            DeviceHeadPort.Write8((byte)(0xE0 | (drive << 4) | ((lba >> 24) & 0x0F)));

            if (operation == SectorOperation.Write)
            {
                CommandPort.Write8(IDECommands.WriteSectorsWithRetry);
            }
            else
            {
                CommandPort.Write8(IDECommands.ReadSectorsWithRetry);
            }

            if (!WaitForRegisterReady())
            {
                return(false);
            }

            DataBlock sector = new DataBlock(data);

            //TODO: Don't use PIO
            if (operation == SectorOperation.Read)
            {
                for (uint index = 0; index < 256; index++)
                {
                    sector.SetUShort(offset + (index * 2), DataPort.Read16());
                }
            }
            else
            {
                for (uint index = 0; index < 256; index++)
                {
                    DataPort.Write16(sector.GetUShort(offset + (index * 2)));
                }
            }

            return(true);
        }
Example #6
0
        /// <summary>
        /// Writes the settings.
        /// </summary>
        /// <param name="settings">The settings.</param>
        protected void WriteSettings(byte[] settings)
        {
            // Write MISCELLANEOUS reg
            miscellaneousOutputWrite.Write8(settings[0]);

            // Write SEQUENCER regs
            for (byte i = 0; i < 5; i++)
            {
                sequencerAddress.Write8(i);
                sequencerData.Write8(settings[1 + i]);
            }

            // Unlock CRTC registers
            crtControllerIndexColor.Write8(0x03);
            crtControllerDataColor.Write8((byte)(crtControllerData.Read8() | 0x80));
            crtControllerIndexColor.Write8(0x11);
            crtControllerDataColor.Write8((byte)(crtControllerData.Read8() & ~0x80));

            // Make sure they remain unlocked
            settings[0x03] = (byte)(settings[0x03] | 0x80);
            settings[0x11] = (byte)(settings[0x11] & ~0x80);

            // Write CRTC regs
            for (byte i = 0; i < 25; i++)
            {
                crtControllerIndexColor.Write8(i);
                crtControllerDataColor.Write8(settings[6 + i]);
            }

            // Write GRAPHICS CONTROLLER regs
            for (byte i = 0; i < 9; i++)
            {
                graphicsControllerAddress.Write8(i);
                graphicsControllerData.Write8(settings[31 + i]);
            }

            // Write ATTRIBUTE CONTROLLER regs
            for (byte i = 0; i < 21; i++)
            {
                inputStatus1ReadB.Read8();
                attributeAddress.Write8(i);
                attributeAddress.Write8(settings[52 + i]);
            }

            // Lock 16-color palette and unblank display */
            inputStatus1ReadB.Read8();
            attributeAddress.Write8(0x20);
        }
Example #7
0
        public override void Start()
        {
            if (Device.Status != DeviceStatus.Available)
            {
                return;
            }

            Device.Status = DeviceStatus.Online;

            byte masterMask;
            byte slaveMask;

            // Save Masks
            masterMask = masterDataPort.Read8();
            slaveMask  = slaveDataPort.Read8();

            // ICW1 - Set Initialize Controller & Expect ICW4
            masterCommandPort.Write8(0x11);

            // ICW2 - interrupt offset
            masterDataPort.Write8(MasterIRQBase);

            // ICW3
            masterDataPort.Write8(0x04);

            // ICW4 - Set 8086 Mode
            masterDataPort.Write8(0x01);

            // ICW1 - Set Initialize Controller & Expect ICW4
            slaveCommandPort.Write8(0x11);

            // ICW2 - interrupt offset
            slaveDataPort.Write8(SlaveIRQBase);

            // ICW3
            slaveDataPort.Write8(0x02);

            // ICW4 - Set 8086 Mode
            slaveDataPort.Write8(0x01);

            // Restore Masks
            masterDataPort.Write8(masterMask);
            slaveDataPort.Write8(slaveMask);

            DisableIRQs();
        }
Example #8
0
 /// <summary>
 /// Reads the specified address.
 /// </summary>
 /// <param name="address">The address.</param>
 /// <returns></returns>
 public byte Read(byte address)
 {
     lock (_lock)
     {
         commandPort.Write8(address);
         return(dataPort.Read8());
     }
 }
Example #9
0
        /// <summary>
        /// Performs the LBA28.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="drive">The drive NBR.</param>
        /// <param name="lba">The lba.</param>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <returns></returns>
        protected bool PerformLBA28(SectorOperation operation, uint drive, uint lba, byte[] data, uint offset)
        {
            if (drive >= MaximumDriveCount || !driveInfo[drive].Present)
            {
                return(false);
            }

            DeviceHeadPort.Write8((byte)(0xE0 | (drive << 4) | ((lba >> 24) & 0x0F)));
            FeaturePort.Write8(0);
            SectorCountPort.Write8(1);
            LBAHighPort.Write8((byte)((lba >> 16) & 0xFF));
            LBAMidPort.Write8((byte)((lba >> 8) & 0xFF));
            LBALowPort.Write8((byte)(lba & 0xFF));

            CommandPort.Write8((operation == SectorOperation.Write) ? IDECommand.WriteSectorsWithRetry : IDECommand.ReadSectorsWithRetry);

            if (!WaitForReadyStatus())
            {
                return(false);
            }

            var sector = new DataBlock(data);

            //TODO: Don't use PIO
            if (operation == SectorOperation.Read)
            {
                for (uint index = 0; index < 256; index++)
                {
                    sector.SetUShort(offset + (index * 2), DataPort.Read16());
                }
            }
            else
            {
                //NOTE: Transferring 16bits at a time seems to fail(?) to write each second 16bits - transferring 32bits seems to fix this (???)
                for (uint index = 0; index < 128; index++)
                {
                    DataPort.Write32(sector.GetUInt(offset + (index * 4)));
                }

                //Cache flush
                DoCacheFlush();
            }

            return(true);
        }
Example #10
0
        /// <summary>
        /// Reads the specified address.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <returns></returns>
        public byte Read(byte address)
        {
            spinLock.Enter();
            commandPort.Write8(address);
            var b = dataPort.Read8();

            spinLock.Exit();
            return(b);
        }
Example #11
0
        /// <summary>
        /// Starts this hardware device.
        /// </summary>
        public override void Start()
        {
            if (Device.Status != DeviceStatus.Available)
            {
                return;
            }

            ushort timerCount = (ushort)(Frequency / Hz);

            // Set to Mode 3 - Square Wave Generator
            modeControlPort.Write8(SquareWave);
            counter0Divisor.Write8((byte)(timerCount & 0xFF));
            counter0Divisor.Write8((byte)((timerCount & 0xFF00) >> 8));

            tickCount = 0;

            Device.Status = DeviceStatus.Online;
        }
Example #12
0
        public override void Start()
        {
            if (Device.Status != DeviceStatus.Available)
            {
                return;
            }

            vgaEnableController.Write8((byte)(vgaEnableController.Read8() | 0x01));

            // Enable colors
            miscOutputWriter.Write8((byte)(miscOutputReader.Read8() | 0x01));

            // Enable MMIO
            crtcControllerIndex.Write8(0x53);
            crtcControllerData.Write8((byte)(crtcControllerData.Read8() | 0x8));

            // Unlock system registers
            WriteCrtcRegister(0x38, 0x48);
            WriteCrtcRegister(0x39, 0xa5);

            WriteCrtcRegister(0x40, 0x01, 0x01);
            WriteCrtcRegister(0x35, 0x00, 0x30);
            WriteCrtcRegister(0x33, 0x20, 0x72);

            WriteCrtcRegister(0x86, 0x80);
            WriteCrtcRegister(0x90, 0x00);

            // Detect number of MB of installed RAM
            byte[] ramSizes  = new byte[] { 4, 0, 3, 8, 2, 6, 1, 0 };
            int    ramSizeMB = ramSizes[(ReadCrtcRegister(0x36) >> 5) & 0x7];

            // Setup video memory
            memory = Device.Resources.GetMemory((byte)(ramSizeMB * 1024 * 1024));

            // Detect current mclk
            WriteSequenceRegister(0x08, 0x06);
            byte m  = (byte)(ReadSequenceRegister(0x11) & 0x7f);
            byte n  = ReadSequenceRegister(0x10);
            byte n1 = (byte)(n & 0x1f);
            byte n2 = (byte)((n >> 5) & 0x03);

            Device.Status = DeviceStatus.Online;
        }
Example #13
0
        /// <summary>
        /// Gets the palette.
        /// </summary>
        /// <param name="colorIndex">Index of the color.</param>
        /// <returns></returns>
        public Color GetPalette(byte colorIndex)
        {
            Color color = new Color();

            dacPaletteMask.Write8(0xFF);
            dacIndexRead.Write8(colorIndex);
            color.Red   = dacData.Read8();
            color.Green = dacData.Read8();
            color.Blue  = dacData.Read8();

            return(color);
        }
Example #14
0
        /// <summary>
        /// Starts this hardware device.
        /// </summary>
        /// <returns></returns>
        public override DeviceDriverStartStatus Start()
        {
            DeviceHeadPort.Write8(0xA0);

            HAL.Sleep(1000 / 250);             // wait 1/250th of a second

            if ((StatusPort.Read8() & 0x40) == 0x40)
            {
                driveInfo[0].Present = true;
            }

            DeviceHeadPort.Write8(0xB0);

            HAL.Sleep(1000 / 250);             // wait 1/250th of a second

            if ((StatusPort.Read8() & 0x40) == 0x40)
            {
                driveInfo[1].Present = true;
            }

            return(DeviceDriverStartStatus.Started);
        }
Example #15
0
 /// <summary>
 /// Writes to configuration space
 /// </summary>
 /// <param name="bus">The bus.</param>
 /// <param name="slot">The slot.</param>
 /// <param name="function">The function.</param>
 /// <param name="register">The register.</param>
 /// <param name="value">The value.</param>
 public void WriteConfig8(byte bus, byte slot, byte function, byte register, byte value)
 {
     configAddress.Write32(GetIndex(bus, slot, function, register));
     configData.Write8(value);
 }
Example #16
0
        /// <summary>
        /// Probes this instance.
        /// </summary>
        /// <returns></returns>
        public override bool Probe()
        {
            LBALowPort.Write8(0x88);

            return(LBALowPort.Read8() == 0x88);
        }
Example #17
0
 /// <summary>
 /// Sends the command.
 /// </summary>
 /// <param name="command">The command.</param>
 /// <param name="value">The value.</param>
 protected void SendCommand(byte command, byte value)
 {
     activeControllerIndex.Write8(command);
     activeControllerData.Write8(value);
 }
Example #18
0
        private void DoIdentifyDrive(byte index)
        {
            //HAL.DebugWriteLine("Device " + index.ToString() + " ID...");

            driveInfo[index].Present = false;

            //Send the identify command to the selected drive
            DeviceHeadPort.Write8((byte)((index == 0) ? 0xA0 : 0xB0));
            SectorCountPort.Write8(0);
            LBALowPort.Write8(0);
            LBAMidPort.Write8(0);
            LBAHighPort.Write8(0);
            CommandPort.Write8(IDECommand.IdentifyDrive);

            if (StatusPort.Read8() == 0)
            {
                //HAL.DebugWriteLine("Device " + index.ToString() + " doesnt exist...");

                //Drive doesn't exist
                return;
            }

            //Wait until a ready status is present
            if (!WaitForReadyStatus())
            {
                return;                                              //There's no ready status, this drive doesn't exist
            }
            if (LBAMidPort.Read8() != 0 && LBAHighPort.Read8() != 0) //Check if the drive is ATA
            {
                //In this case the drive is ATAPI, which is not supported
                //HAL.DebugWriteLine("Device " + index.ToString() + " not ATA");

                return;
            }

            //Wait until the identify data is present (256x16 bits)
            if (!WaitForIdentifyData())
            {
                //HAL.DebugWriteLine("Device " + index.ToString() + " ID error");
                return;
            }

            //Read the identification info
            var info = new DataBlock(512);

            for (uint ix = 0; ix < 256; ix++)
            {
                info.SetUShort(ix * 2, DataPort.Read16());
            }

            //Find the addressing mode
            bool lba48Supported = ((info.GetUShort(IdentifyDrive.CommandSetSupported83) & 0x200) == 0x200);

            driveInfo[index].AddressingMode = (lba48Supported ? AddressingMode.LBA48 : AddressingMode.LBA28);

            //Find the max LBA count
            uint  lba28SectorCount = info.GetUInt(IdentifyDrive.MaxLBA28);
            ulong lba48SectorCount = info.GetULong(IdentifyDrive.MaxLBA48);

            //HAL.DebugWriteLine("LBA48BIT=" + lba48Supported.ToString());
            //HAL.DebugWriteLine("LBA28   =" + lba28SectorCount.ToString("X2"));

            if (!lba48Supported)            //No LBA48
            {
                driveInfo[index].MaxLBA = lba28SectorCount;
            }
            else                                    //LBA48 supported
            {
                if (lba28SectorCount == 0x0FFFFFFF) //Check the limit according to the d1699r3f-ata8-acs.pdf (4.10.4 IDENTIFY DEVICE data)
                {
                    driveInfo[index].MaxLBA = (uint)lba48SectorCount;
                }
                else
                {
                    driveInfo[index].MaxLBA = lba28SectorCount;
                }
            }

            //An ATA drive is present and ready to use
            driveInfo[index].Present = true;

            //HAL.DebugWriteLine("Device " + index.ToString() + " present - MaxLBA=" + driveInfo[index].MaxLBA.ToString());
        }
Example #19
0
        private void DoIdentifyDrive(byte index)
        {
            driveInfo[index].Present = false;

            //Send the identify command to the selected drive
            DeviceHeadPort.Write8((byte)((index == 0) ? 0xA0 : 0xB0));
            SectorCountPort.Write8(0);
            LBALowPort.Write8(0);
            LBAMidPort.Write8(0);
            LBAHighPort.Write8(0);
            CommandPort.Write8(IDECommand.IdentifyDrive);

            if (StatusPort.Read8() == 0)
            {
                //Drive doesn't exist
                return;
            }

            //Wait until a ready status is present
            if (!WaitForReadyStatus())
            {
                return;                 //There's no ready status, this drive doesn't exist
            }

            if (LBAMidPort.Read8() != 0 && LBAHighPort.Read8() != 0)             //Check if the drive is ATA
            {
                //In this case the drive is ATAPI
                //HAL.DebugWriteLine("Device " + index.ToString() + " not ATA");
                return;
            }

            //Wait until the identify data is present (256x16 bits)
            if (!WaitForIdentifyData())
            {
                //HAL.DebugWriteLine("Device " + index.ToString() + " ID error");
                return;
            }

            //An ATA drive is present
            driveInfo[index].Present = true;

            //Read the identification info
            var info = new DataBlock(512);

            for (uint ix = 0; ix < 256; ix++)
            {
                info.SetUShort(ix * 2, DataPort.Read16());
            }

            //Find the addressing mode
            var lba28SectorCount = info.GetUInt(IdentifyDrive.MaxLBA28);

            AddressingMode aMode = AddressingMode.NotSupported;

            if ((info.GetUShort(IdentifyDrive.CommandSetSupported83) & 0x200) == 0x200)             //Check the LBA48 support bit
            {
                aMode = AddressingMode.LBA48;
                driveInfo[index].MaxLBA = info.GetUInt(IdentifyDrive.MaxLBA48);
            }
            else if (lba28SectorCount > 0)             //LBA48 not supported, check LBA28
            {
                aMode = AddressingMode.LBA28;
                driveInfo[index].MaxLBA = lba28SectorCount;
            }

            driveInfo[index].AddressingMode = aMode;

            //HAL.DebugWriteLine("Device " + index.ToString() + " present - MaxLBA=" + driveInfo[index].MaxLBA.ToString());
        }