1 /**
2  ** vd_mem.c ---- driver for creating image in memory for later exporting
3  **
4  ** Author:  Andris Pavenis
5  ** [e-mail: pavenis@acad.latnet.lv]
6  **
7  ** This file is part of the GRX graphics library.
8  **
9  ** The GRX graphics library is free software; you can redistribute it
10  ** and/or modify it under some conditions; see the "copying.grx" file
11  ** for details.
12  **
13  ** This library is distributed in the hope that it will be useful,
14  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  **
17  **/
18 
19 #include <stdio.h>
20 
21 #include "libgrx.h"
22 #include "grdriver.h"
23 #include "allocate.h"
24 #include "arith.h"
25 #include "int86.h"
26 #include "memfill.h"
27 
28 
29 static  char far * MemBuf = NULL;
30 static  unsigned long MemBufSze = 0;
31 
FreeMemBuf(void)32 static void FreeMemBuf(void) {
33   if (MemBuf) farfree(MemBuf);
34   MemBuf = NULL;
35   MemBufSze = 0;
36 }
37 
AllocMemBuf(unsigned long sze)38 static int AllocMemBuf(unsigned long sze) {
39   int clear = 1;
40   if (!MemBuf) {
41     MemBuf = farcalloc(1,(size_t)sze);
42     if (!MemBuf) return 0;
43     MemBufSze = sze;
44     clear = 0;
45   }
46   if (MemBufSze < sze) {
47     MemBuf = farrealloc(MemBuf,(size_t)sze);
48     if (!MemBuf) return 0;
49     MemBufSze = sze;
50   }
51   if (clear) memzero(MemBuf,sze);
52   return 1;
53 }
54 
55 static int mem_setmode (GrVideoMode *mp,int noclear);
56 
57 
58 static GrVideoModeExt gr1ext = {
59     GR_frameRAM1,                       /* frame driver */
60     NULL,                               /* frame driver override */
61     0,                                  /* frame buffer address */
62     { 1, 1, 1 },                        /* color precisions */
63     { 0, 0, 0 },                        /* color component bit positions */
64     GR_VMODEF_MEMORY,                   /* mode flag bits */
65     mem_setmode,                        /* mode set */
66     NULL,                               /* virtual size set */
67     NULL,                               /* virtual scroll */
68     NULL,                               /* bank set function */
69     NULL,                               /* double bank set function */
70     NULL                                /* color loader */
71 };
72 
73 static GrVideoModeExt gr4ext = {
74     GR_frameRAM4,                       /* frame driver */
75     NULL,                               /* frame driver override */
76     NULL,                               /* frame buffer address */
77     { 8, 8, 8 },                        /* color precisions */
78     { 0, 0, 0 },                        /* color component bit positions */
79     GR_VMODEF_MEMORY,                   /* mode flag bits */
80     mem_setmode,                        /* mode set */
81     NULL,                               /* virtual size set */
82     NULL,                               /* virtual scroll */
83     NULL,                               /* bank set function */
84     NULL,                               /* double bank set function */
85     NULL                                /* color loader */
86 };
87 
88 static GrVideoModeExt gr8ext = {
89     GR_frameRAM8,                       /* frame driver */
90     NULL,                               /* frame driver override */
91     NULL,                               /* frame buffer address */
92     { 8, 8, 8 },                        /* color precisions */
93     { 0, 0, 0 },                        /* color component bit positions */
94     GR_VMODEF_MEMORY,                   /* mode flag bits */
95     mem_setmode,                        /* mode set */
96     NULL,                               /* virtual size set */
97     NULL,                               /* virtual scroll */
98     NULL,                               /* bank set function */
99     NULL,                               /* double bank set function */
100     NULL                                /* color loader */
101 };
102 
103 static GrVideoModeExt gr24ext = {
104 #ifdef GRX_USE_RAM3x8
105     GR_frameRAM3x8,                     /* frame driver */
106 #else
107     GR_frameRAM24,                      /* frame driver */
108 #endif
109     NULL,                               /* frame driver override */
110     NULL,                               /* frame buffer address */
111     { 8, 8, 8 },                        /* color precisions */
112     { 0, 0, 0 },                        /* color component bit positions */
113     GR_VMODEF_MEMORY,                   /* mode flag bits */
114     mem_setmode,                        /* mode set */
115     NULL,                               /* virtual size set */
116     NULL,                               /* virtual scroll */
117     NULL,                               /* bank set function */
118     NULL,                               /* double bank set function */
119     NULL                                /* color loader */
120 };
121 
122 
dummymode(GrVideoMode * mp,int noclear)123 static int dummymode (GrVideoMode * mp , int noclear )
124 {
125     FreeMemBuf();
126     return TRUE;
127 }
128 
129 
130 GrVideoModeExt   dummyExt = {
131     GR_frameText,                       /* frame driver */
132     NULL,                               /* frame driver override */
133     MK_FP(0xb800,0),                    /* frame buffer address */
134     { 0, 0, 0 },                        /* color precisions */
135     { 0, 0, 0 },                        /* color component bit positions */
136     0,                                  /* mode flag bits */
137     dummymode,                          /* mode set */
138     NULL,                               /* virtual size set */
139     NULL,                               /* virtual scroll */
140     NULL,                               /* bank set function */
141     NULL,                               /* double bank set function */
142     NULL                                /* color loader */
143 };
144 
145 
146 
147 
148 static GrVideoMode modes[] = {
149     /* pres.  bpp wdt   hgt   BIOS   scan  priv. &ext                             */
150     {  TRUE,  1,  640,  480,  0x00,   80,    0,  &gr1ext                          },
151     {  TRUE,  4,  640,  480,  0x00,  320,    0,  &gr4ext                          },
152     {  TRUE,  8,  640,  480,  0x00,  640,    0,  &gr8ext                          },
153     {  TRUE, 24,  640,  480,  0x00, 1920,    0,  &gr24ext                         },
154     {  TRUE,  1,   80,   25,  0x00,  160,    0,  &dummyExt                        }
155 };
156 
157 
158 
mem_setmode(GrVideoMode * mp,int noclear)159 static int mem_setmode (GrVideoMode *mp,int noclear)
160 {
161      return MemBuf ? TRUE : FALSE;
162 }
163 
164 
165 
mem_selectmode(GrVideoDriver * drv,int w,int h,int bpp,int txt,unsigned int * ep)166 static GrVideoMode * mem_selectmode ( GrVideoDriver * drv, int w, int h,
167 				      int bpp, int txt, unsigned int * ep )
168 {
169     int  index;
170     unsigned long  size;
171     int  LineOffset;
172 
173     if (txt) return _gr_selectmode (drv,w,h,bpp,txt,ep);
174 /* why ???
175     if (w<320) w=320;
176     if (h<240) h=240;
177 */
178     if (w < 1 || h < 1) return NULL;
179 
180     switch (bpp)
181       {
182 	 case 1:   index = 0;
183 		   LineOffset = (w + 7) >> 3;
184 		   size = h;
185 		   break;
186 	 case 4:   index = 1;
187 		   LineOffset = (w + 7) >> 3;
188 		   size = 4*h;
189 		   break;
190 	 case 8:   index = 2;
191 		   LineOffset = w;
192 		   size = h;
193 		   break;
194 	 case 24:  index = 3;
195 #ifdef GRX_USE_RAM3x8
196                    LineOffset = w;
197 		   size = 3*h;
198 #else
199 		   LineOffset = 3*w;
200 		   size = h;
201 #endif
202 		   break;
203 	 default:  return NULL;
204       }
205 
206     LineOffset = (LineOffset+7) & (~7); /* align rows to 64bit boundary */
207     size *= LineOffset;
208 
209     if (((size_t)size) != size) return NULL;
210 
211 			       /* why ???       */
212     modes[index].width       = /* w<320 ? 320 : */ w;
213     modes[index].height      = /* h<200 ? 200 : */ h;
214     modes[index].bpp         = bpp;
215     modes[index].lineoffset  = LineOffset;
216 
217     if ( AllocMemBuf(size) ) {
218 	modes[index].extinfo->frame = MemBuf;
219         return _gr_selectmode (drv,w,h,bpp,txt,ep);
220     }
221     return FALSE;
222 }
223 
224 
225 /*
226 static int detect (void)
227 {
228 	return TRUE;
229 }
230 */
231 
mem_reset(void)232 static void mem_reset (void)
233 {
234     if(DRVINFO->moderestore) {
235       FreeMemBuf();
236     }
237 }
238 
239 
240 GrVideoDriver _GrDriverMEM = {
241     "memory",                           /* name */
242     GR_MEM,                             /* adapter type */
243     NULL,                               /* inherit modes from this driver */
244     modes,                              /* mode table */
245     itemsof(modes),                     /* # of modes */
246     NULL, /* detect, */                 /* detection routine */
247     NULL,                               /* initialization routine */
248     mem_reset,                          /* reset routine */
249     mem_selectmode,                     /* special mode select routine */
250     GR_DRIVERF_USER_RESOLUTION          /* arbitrary resolution possible */
251 };
252 
253