/// <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; } }
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; } }