1 /* 2 * PROJECT: ReactOS VGA display driver 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: win32ss/drivers/displays/vga/objects/offscreen.c 5 * PURPOSE: Manages off-screen video memory 6 * PROGRAMMERS: Copyright (C) 1998-2001 ReactOS Team 7 */ 8 9 /* INCLUDES ******************************************************************/ 10 11 #include <vgaddi.h> 12 13 /* GLOBALS *******************************************************************/ 14 15 static LIST_ENTRY SavedBitsList; 16 17 /* FUNCTIONS *****************************************************************/ 18 19 VOID 20 VGADDI_BltFromSavedScreenBits( 21 IN ULONG DestX, 22 IN ULONG DestY, 23 IN PSAVED_SCREEN_BITS Src, 24 IN ULONG SizeX, 25 IN ULONG SizeY) 26 { 27 PUCHAR DestOffset; 28 PUCHAR SrcOffset; 29 ULONG i, j; 30 31 /* Select write mode 1. */ 32 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); 33 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 1); 34 35 SrcOffset = (PUCHAR)vidmem + Src->Offset; 36 for (i = 0; i < SizeY; i++) 37 { 38 DestOffset = (PUCHAR)vidmem + (i + DestY) * 80 + (DestX >> 3); 39 //FIXME: in the loop below we should treat the case when SizeX is not divisible by 8, i.e. partial bytes 40 for (j = 0; j < SizeX>>3; j++, SrcOffset++, DestOffset++) 41 { 42 (VOID)READ_REGISTER_UCHAR(SrcOffset); 43 WRITE_REGISTER_UCHAR(DestOffset, 0); 44 } 45 } 46 47 /* Select write mode 2. */ 48 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); 49 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2); 50 } 51 52 VOID 53 VGADDI_BltToSavedScreenBits( 54 IN PSAVED_SCREEN_BITS Dest, 55 IN ULONG SourceX, 56 IN ULONG SourceY, 57 IN ULONG SizeX, 58 IN ULONG SizeY) 59 { 60 PUCHAR DestOffset; 61 PUCHAR SrcOffset; 62 ULONG i, j; 63 64 /* Select write mode 1. */ 65 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); 66 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 1); 67 68 DestOffset = (PUCHAR)vidmem + Dest->Offset; 69 70 for (i = 0; i < SizeY; i++) 71 { 72 SrcOffset = (PUCHAR)vidmem + (SourceY + i) * 80 + (SourceX >> 3); 73 //FIXME: in the loop below we should treat the case when SizeX is not divisible by 8, i.e. partial bytes 74 for (j = 0; j < SizeX>>3; j++, SrcOffset++, DestOffset++) 75 { 76 (VOID)READ_REGISTER_UCHAR(SrcOffset); 77 WRITE_REGISTER_UCHAR(DestOffset, 0); 78 } 79 } 80 81 /* Select write mode 2. */ 82 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); 83 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2); 84 } 85 86 VOID 87 VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits) 88 { 89 SavedBits->Free = TRUE; 90 91 if (SavedBits->ListEntry.Blink != &SavedBitsList) 92 { 93 PSAVED_SCREEN_BITS Previous; 94 95 Previous = CONTAINING_RECORD(SavedBits->ListEntry.Blink, 96 SAVED_SCREEN_BITS, ListEntry); 97 if (Previous->Free) 98 { 99 Previous->Size += SavedBits->Size; 100 RemoveEntryList(&SavedBits->ListEntry); 101 EngFreeMem(SavedBits); 102 SavedBits = Previous; 103 } 104 } 105 if (SavedBits->ListEntry.Flink != &SavedBitsList) 106 { 107 PSAVED_SCREEN_BITS Next; 108 109 Next = CONTAINING_RECORD(SavedBits->ListEntry.Flink, SAVED_SCREEN_BITS, 110 ListEntry); 111 if (Next->Free) 112 { 113 SavedBits->Size += Next->Size; 114 RemoveEntryList(&SavedBits->ListEntry); 115 EngFreeMem(SavedBits); 116 } 117 } 118 } 119 120 PSAVED_SCREEN_BITS 121 VGADDI_AllocSavedScreenBits(ULONG Size) 122 { 123 PSAVED_SCREEN_BITS Current; 124 PLIST_ENTRY CurrentEntry; 125 PSAVED_SCREEN_BITS Best; 126 PSAVED_SCREEN_BITS New; 127 128 Best = NULL; 129 CurrentEntry = SavedBitsList.Flink; 130 while (CurrentEntry != &SavedBitsList) 131 { 132 Current = CONTAINING_RECORD(CurrentEntry, SAVED_SCREEN_BITS, ListEntry); 133 134 if (Current->Free && Current->Size >= Size && 135 (Best == NULL || (Current->Size - Size) < (Best->Size - Size))) 136 { 137 Best = Current; 138 } 139 140 CurrentEntry = CurrentEntry->Flink; 141 } 142 143 if (!Best) 144 return NULL; 145 146 if (Best->Size == Size) 147 { 148 Best->Free = FALSE; 149 return Best; 150 } 151 else 152 { 153 New = EngAllocMem(0, sizeof(SAVED_SCREEN_BITS), ALLOC_TAG); 154 New->Free = FALSE; 155 New->Offset = Best->Offset + Size; 156 New->Size = Size; 157 Best->Size -= Size; 158 InsertHeadList(&Best->ListEntry, &New->ListEntry); 159 return New; 160 } 161 } 162 163 VOID 164 VGADDI_InitializeOffScreenMem( 165 IN ULONG Start, 166 IN ULONG Length) 167 { 168 PSAVED_SCREEN_BITS FreeBits; 169 170 InitializeListHead(&SavedBitsList); 171 172 FreeBits = EngAllocMem(0, sizeof(SAVED_SCREEN_BITS), ALLOC_TAG); 173 FreeBits->Free = TRUE; 174 FreeBits->Offset = Start; 175 FreeBits->Size = Length; 176 InsertHeadList(&SavedBitsList, &FreeBits->ListEntry); 177 } 178