Beispiel #1
0
        /// <summary>
        /// Initializes a new display mode.
        /// </summary>
        /// <param name="mode">New display mode.</param>
        public void SetDisplayMode(VideoMode mode)
        {
            this.CurrentMode = mode;
            mode.InitializeMode(this);
            Graphics.WriteRegister(GraphicsRegister.ColorDontCare, 0x0F);

            if (this.defaultPaletteLoading)
            {
                Dac.Reset();
            }

            VirtualMachine.OnVideoModeChanged(EventArgs.Empty);
        }
Beispiel #2
0
 private protected VideoMode(int width, int height, VideoMode baseMode)
 {
     this.Width               = width;
     this.Height              = height;
     this.BitsPerPixel        = baseMode.BitsPerPixel;
     this.IsPlanar            = baseMode.IsPlanar;
     this.FontHeight          = baseMode.FontHeight;
     this.VideoModeType       = baseMode.VideoModeType;
     this.dac                 = baseMode.dac;
     this.crtController       = baseMode.crtController;
     this.attributeController = baseMode.attributeController;
     this.VideoRam            = baseMode.VideoRam;
 }
Beispiel #3
0
        public byte ReadByte(int port)
        {
            switch (port)
            {
            case Ports.DacAddressReadMode:
                return(Dac.ReadIndex);

            case Ports.DacAddressWriteMode:
                return(Dac.WriteIndex);

            case Ports.DacData:
                return(Dac.Read());

            case Ports.GraphicsControllerAddress:
                return((byte)graphicsRegister);

            case Ports.GraphicsControllerData:
                return(Graphics.ReadRegister(graphicsRegister));

            case Ports.SequencerAddress:
                return((byte)sequencerRegister);

            case Ports.SequencerData:
                return(Sequencer.ReadRegister(sequencerRegister));

            case Ports.AttributeAddress:
                return((byte)attributeRegister);

            case Ports.AttributeData:
                return(AttributeController.ReadRegister(attributeRegister));

            case Ports.CrtControllerAddress:
            case Ports.CrtControllerAddressAlt:
                return((byte)crtRegister);

            case Ports.CrtControllerData:
            case Ports.CrtControllerDataAlt:
                return(CrtController.ReadRegister(crtRegister));

            case Ports.InputStatus1Read:
            case Ports.InputStatus1ReadAlt:
                attributeDataMode = false;
                return(GetInputStatus1Value());

            default:
                return(0);
            }
        }
Beispiel #4
0
        private protected VideoMode(int width, int height, int bpp, bool planar, int fontHeight, VideoModeType modeType, VideoHandler video)
        {
            this.Width               = width;
            this.Height              = height;
            this.OriginalHeight      = height;
            this.BitsPerPixel        = bpp;
            this.IsPlanar            = planar;
            this.FontHeight          = fontHeight;
            this.VideoModeType       = modeType;
            this.dac                 = video.Dac;
            this.crtController       = video.CrtController;
            this.attributeController = video.AttributeController;
            this.VideoRam            = GetVideoRamPointer(video);

            InitializeFont(video.VirtualMachine.PhysicalMemory);
        }
Beispiel #5
0
        /// <summary>
        /// Sets DAC color registers to values in emulated RAM.
        /// </summary>
        private void SetDacRegisters()
        {
            ushort segment = VirtualMachine.Processor.ES;
            uint   offset  = (ushort)VirtualMachine.Processor.DX;
            int    start   = VirtualMachine.Processor.BX;
            int    count   = VirtualMachine.Processor.CX;

            for (int i = start; i < count; i++)
            {
                byte r = VirtualMachine.PhysicalMemory.GetByte(segment, offset);
                byte g = VirtualMachine.PhysicalMemory.GetByte(segment, offset + 1u);
                byte b = VirtualMachine.PhysicalMemory.GetByte(segment, offset + 2u);

                Dac.SetColor((byte)(start + i), r, g, b);

                offset += 3u;
            }
        }
Beispiel #6
0
        public void WriteByte(int port, byte value)
        {
            switch (port)
            {
            case Ports.DacAddressReadMode:
                Dac.ReadIndex = value;
                break;

            case Ports.DacAddressWriteMode:
                Dac.WriteIndex = value;
                break;

            case Ports.DacData:
                Dac.Write(value);
                break;

            case Ports.GraphicsControllerAddress:
                graphicsRegister = (GraphicsRegister)value;
                break;

            case Ports.GraphicsControllerData:
                Graphics.WriteRegister(graphicsRegister, value);
                break;

            case Ports.SequencerAddress:
                sequencerRegister = (SequencerRegister)value;
                break;

            case Ports.SequencerData:
                var previousMode = Sequencer.SequencerMemoryMode;
                Sequencer.WriteRegister(sequencerRegister, value);
                if ((previousMode & SequencerMemoryMode.Chain4) == SequencerMemoryMode.Chain4 && (Sequencer.SequencerMemoryMode & SequencerMemoryMode.Chain4) == 0)
                {
                    EnterModeX();
                }
                break;

            case Ports.AttributeAddress:
                if (!attributeDataMode)
                {
                    attributeRegister = (AttributeControllerRegister)(value & 0x1F);
                }
                else
                {
                    AttributeController.WriteRegister(attributeRegister, value);
                }
                attributeDataMode = !attributeDataMode;
                break;

            case Ports.AttributeData:
                AttributeController.WriteRegister(attributeRegister, value);
                break;

            case Ports.CrtControllerAddress:
            case Ports.CrtControllerAddressAlt:
                crtRegister = (CrtControllerRegister)value;
                break;

            case Ports.CrtControllerData:
            case Ports.CrtControllerDataAlt:
                int previousVerticalEnd = CrtController.VerticalDisplayEnd;
                CrtController.WriteRegister(crtRegister, value);
                if (previousVerticalEnd != CrtController.VerticalDisplayEnd)
                {
                    ChangeVerticalEnd();
                }
                break;
            }
        }
Beispiel #7
0
        void IInterruptHandler.HandleInterrupt(int interrupt)
        {
            switch (VirtualMachine.Processor.AH)
            {
            case 0x4F:
                this.vbe.HandleFunction();
                break;

            case Functions.GetDisplayMode:
                VirtualMachine.Processor.AH = VirtualMachine.PhysicalMemory.Bios.ScreenColumns;
                VirtualMachine.Processor.AL = (byte)VirtualMachine.PhysicalMemory.Bios.VideoMode;
                break;

            case Functions.ScrollUpWindow:
                //if(vm.Processor.AL == 0)
                //    textDisplay.Clear();
                //else
            {
                byte foreground = (byte)((VirtualMachine.Processor.BX >> 8) & 0x0F);
                byte background = (byte)((VirtualMachine.Processor.BX >> 12) & 0x0F);
                TextConsole.ScrollTextUp(VirtualMachine.Processor.CL, VirtualMachine.Processor.CH, VirtualMachine.Processor.DL, VirtualMachine.Processor.DH, VirtualMachine.Processor.AL, foreground, background);
            }
            break;

            case Functions.EGA:
                switch (VirtualMachine.Processor.BL)
                {
                case Functions.EGA_GetInfo:
                    VirtualMachine.Processor.BX = 0x03;         // 256k installed
                    VirtualMachine.Processor.CX = 0x09;         // EGA switches set
                    break;

                case Functions.EGA_SelectVerticalResolution:
                    if (VirtualMachine.Processor.AL == 0)
                    {
                        this.verticalTextResolution = 8;
                    }
                    else if (VirtualMachine.Processor.AL == 1)
                    {
                        this.verticalTextResolution = 14;
                    }
                    else
                    {
                        this.verticalTextResolution = 16;
                    }
                    VirtualMachine.Processor.AL = 0x12;         // Success
                    break;

                case Functions.EGA_PaletteLoading:
                    this.defaultPaletteLoading = VirtualMachine.Processor.AL == 0;
                    break;

                default:
                    System.Diagnostics.Debug.WriteLine(string.Format("Video command {0:X2}, BL={1:X2}h not implemented.", Functions.EGA, VirtualMachine.Processor.BL));
                    break;
                }
                break;

            case Functions.ReadCharacterAndAttributeAtCursor:
                VirtualMachine.Processor.AX = (short)TextConsole.GetCharacter(TextConsole.CursorPosition.X, TextConsole.CursorPosition.Y);
                break;

            case Functions.WriteCharacterAndAttributeAtCursor:
                TextConsole.Write(VirtualMachine.Processor.AL, (byte)(VirtualMachine.Processor.BL & 0x0F), (byte)(VirtualMachine.Processor.BL >> 4), false);
                break;

            case Functions.WriteCharacterAtCursor:
                TextConsole.Write(VirtualMachine.Processor.AL);
                break;

            case Functions.GetDisplayCombinationCode:
                VirtualMachine.Processor.AL = 0x1A;
                VirtualMachine.Processor.BX = 0x0008;
                break;

            case Functions.SetDisplayMode:
                SetDisplayMode((VideoMode10)VirtualMachine.Processor.AL);
                break;

            case Functions.SetCursorPosition:
                TextConsole.CursorPosition = new Point(VirtualMachine.Processor.DL, VirtualMachine.Processor.DH);
                break;

            case Functions.SetCursorShape:
                SetCursorShape(VirtualMachine.Processor.CH, VirtualMachine.Processor.CL);
                break;

            case Functions.SelectActiveDisplayPage:
                this.CurrentMode.ActiveDisplayPage = VirtualMachine.Processor.AL;
                break;

            case Functions.Palette:
                switch (VirtualMachine.Processor.AL)
                {
                case Functions.Palette_SetSingleRegister:
                    SetEgaPaletteRegister(VirtualMachine.Processor.BL, VirtualMachine.Processor.BH);
                    break;

                case Functions.Palette_SetBorderColor:
                    // Ignore for now.
                    break;

                case Functions.Palette_SetAllRegisters:
                    SetAllEgaPaletteRegisters();
                    break;

                case Functions.Palette_ReadSingleDacRegister:
                    // These are commented out because they cause weird issues sometimes.
                    //vm.Processor.DH = (byte)((dac.Palette[vm.Processor.BL] >> 18) & 0xCF);
                    //vm.Processor.CH = (byte)((dac.Palette[vm.Processor.BL] >> 10) & 0xCF);
                    //vm.Processor.CL = (byte)((dac.Palette[vm.Processor.BL] >> 2) & 0xCF);
                    break;

                case Functions.Palette_SetSingleDacRegister:
                    Dac.SetColor(VirtualMachine.Processor.BL, VirtualMachine.Processor.DH, VirtualMachine.Processor.CH, VirtualMachine.Processor.CL);
                    break;

                case Functions.Palette_SetDacRegisters:
                    SetDacRegisters();
                    break;

                case Functions.Palette_ReadDacRegisters:
                    ReadDacRegisters();
                    break;

                case Functions.Palette_ToggleBlink:
                    // Blinking is not emulated.
                    break;

                case Functions.Palette_SelectDacColorPage:
                    System.Diagnostics.Debug.WriteLine("Select DAC color page");
                    break;

                default:
                    throw new NotImplementedException(string.Format("Video command 10{0:X2}h not implemented.", VirtualMachine.Processor.AL));
                }
                break;

            case Functions.GetCursorPosition:
                VirtualMachine.Processor.CH = 14;
                VirtualMachine.Processor.CL = 15;
                VirtualMachine.Processor.DH = (byte)TextConsole.CursorPosition.Y;
                VirtualMachine.Processor.DL = (byte)TextConsole.CursorPosition.X;
                break;

            case Functions.TeletypeOutput:
                TextConsole.Write(VirtualMachine.Processor.AL);
                break;

            case Functions.GetFunctionalityInfo:
                GetFunctionalityInfo();
                break;

            case 0xEF:
                VirtualMachine.Processor.DX = -1;
                break;

            case 0xFE:
                break;

            case Functions.Font:
                switch (VirtualMachine.Processor.AL)
                {
                case Functions.Font_GetFontInfo:
                    GetFontInfo();
                    break;

                case Functions.Font_Load8x8:
                    SwitchTo80x50TextMode();
                    break;

                case Functions.Font_Load8x16:
                    break;

                default:
                    throw new NotImplementedException(string.Format("Video command 11{0:X2}h not implemented.", VirtualMachine.Processor.AL));
                }
                break;

            default:
                System.Diagnostics.Debug.WriteLine(string.Format("Video command {0:X2}h not implemented.", VirtualMachine.Processor.AH));
                break;
            }
        }