2 * PROJECT: ReactOS VGA display driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/video/displays/vga/objects/offscreen.c
5 * PURPOSE: Manages off-screen video memory
6 * PROGRAMMERS: Copyright (C) 1998-2001 ReactOS Team
9 /* INCLUDES ******************************************************************/
13 /* GLOBALS *******************************************************************/
15 static LIST_ENTRY SavedBitsList
;
17 /* FUNCTIONS *****************************************************************/
20 VGADDI_BltFromSavedScreenBits(
23 IN PSAVED_SCREEN_BITS Src
,
31 /* Select write mode 1. */
32 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 5);
33 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 1);
35 SrcOffset
= (PUCHAR
)vidmem
+ Src
->Offset
;
36 for (i
= 0; i
< SizeY
; i
++)
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
++)
42 (VOID
)READ_REGISTER_UCHAR(SrcOffset
);
43 WRITE_REGISTER_UCHAR(DestOffset
, 0);
47 /* Select write mode 2. */
48 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 5);
49 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 2);
53 VGADDI_BltToSavedScreenBits(
54 IN PSAVED_SCREEN_BITS Dest
,
64 /* Select write mode 1. */
65 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 5);
66 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 1);
68 DestOffset
= (PUCHAR
)vidmem
+ Dest
->Offset
;
70 for (i
= 0; i
< SizeY
; i
++)
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
++)
76 (VOID
)READ_REGISTER_UCHAR(SrcOffset
);
77 WRITE_REGISTER_UCHAR(DestOffset
, 0);
81 /* Select write mode 2. */
82 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 5);
83 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 2);
87 VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits
)
89 SavedBits
->Free
= TRUE
;
91 if (SavedBits
->ListEntry
.Blink
!= &SavedBitsList
)
93 PSAVED_SCREEN_BITS Previous
;
95 Previous
= CONTAINING_RECORD(SavedBits
->ListEntry
.Blink
,
96 SAVED_SCREEN_BITS
, ListEntry
);
99 Previous
->Size
+= SavedBits
->Size
;
100 RemoveEntryList(&SavedBits
->ListEntry
);
101 EngFreeMem(SavedBits
);
102 SavedBits
= Previous
;
105 if (SavedBits
->ListEntry
.Flink
!= &SavedBitsList
)
107 PSAVED_SCREEN_BITS Next
;
109 Next
= CONTAINING_RECORD(SavedBits
->ListEntry
.Flink
, SAVED_SCREEN_BITS
,
113 SavedBits
->Size
+= Next
->Size
;
114 RemoveEntryList(&SavedBits
->ListEntry
);
115 EngFreeMem(SavedBits
);
121 VGADDI_AllocSavedScreenBits(ULONG Size
)
123 PSAVED_SCREEN_BITS Current
;
124 PLIST_ENTRY CurrentEntry
;
125 PSAVED_SCREEN_BITS Best
;
126 PSAVED_SCREEN_BITS New
;
129 CurrentEntry
= SavedBitsList
.Flink
;
130 while (CurrentEntry
!= &SavedBitsList
)
132 Current
= CONTAINING_RECORD(CurrentEntry
, SAVED_SCREEN_BITS
, ListEntry
);
134 if (Current
->Free
&& Current
->Size
>= Size
&&
135 (Best
== NULL
|| (Current
->Size
- Size
) < (Best
->Size
- Size
)))
140 CurrentEntry
= CurrentEntry
->Flink
;
146 if (Best
->Size
== Size
)
153 New
= EngAllocMem(0, sizeof(SAVED_SCREEN_BITS
), ALLOC_TAG
);
155 New
->Offset
= Best
->Offset
+ Size
;
158 InsertHeadList(&Best
->ListEntry
, &New
->ListEntry
);
164 VGADDI_InitializeOffScreenMem(
168 PSAVED_SCREEN_BITS FreeBits
;
170 InitializeListHead(&SavedBitsList
);
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
);