3 * Common Driver/Filesystem Helper Functions
7 #include <api_drv_disk.h>
8 #include <api_drv_video.h>
13 //int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length, tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers);
14 //size_t DrvUtil_Video_WriteLFB(int Mode, tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Src);
15 void DrvUtil_Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);
16 void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);
19 tDrvUtil_Video_2DHandlers gDrvUtil_Stub_2DFunctions = {
21 DrvUtil_Video_2D_Fill,
26 // --- Video Driver Helpers ---
27 int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
28 tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers)
30 void *stream = Buffer;
37 stream = (void*)((tVAddr)stream + 1);
39 if(op > NUM_VIDEO_2DOPS) {
40 Log_Warning("DrvUtil",
41 "DrvUtil_Video_2DStream: Unknown operation %i",
46 if(op*sizeof(void*) > SizeofHandlers) {
47 Log_Warning("DrvUtil",
48 "DrvUtil_Video_2DStream: Driver does not support op %i",
55 case VIDEO_2DOP_NOP: break;
58 if(rem < 12) return Length-rem;
61 Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
62 " does not support VIDEO_2DOP_FILL");
68 ((Uint16*)stream)[0], ((Uint16*)stream)[1],
69 ((Uint16*)stream)[2], ((Uint16*)stream)[3],
74 stream = (void*)((tVAddr)stream + 12);
78 if(rem < 12) return Length-rem;
81 Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
82 " does not support VIDEO_2DOP_BLIT");
88 ((Uint16*)stream)[0], ((Uint16*)stream)[1],
89 ((Uint16*)stream)[2], ((Uint16*)stream)[3],
90 ((Uint16*)stream)[4], ((Uint16*)stream)[5]
94 stream = (void*)((tVAddr)stream + 12);
102 int DrvUtil_Video_WriteLFB(int Mode, tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Buffer)
105 ENTER("iMode pFBInfo xOffset xLength pBuffer",
106 Mode, FBInfo, Offset, Length, Buffer);
109 case VIDEO_BUFFMT_TEXT:
111 tVT_Char *chars = Buffer;
112 int bytes_per_px = (FBInfo->Depth + 7) / 8;
113 int widthInChars = FBInfo->Width/giVT_CharWidth;
114 int heightInChars = FBInfo->Height/giVT_CharHeight;
117 LOG("bytes_per_px = %i", bytes_per_px);
118 LOG("widthInChars = %i, heightInChars = %i", widthInChars, heightInChars);
120 Length /= sizeof(tVT_Char); Offset /= sizeof(tVT_Char);
122 x = Offset % widthInChars; y = Offset / widthInChars;
123 LOG("x = %i, y = %i", x, y);
126 if(Offset > heightInChars * widthInChars) LEAVE_RET('i', 0);
127 if(y >= heightInChars) LEAVE_RET('i', 0);
129 if( Offset + Length > heightInChars*widthInChars )
131 Length = heightInChars*widthInChars - Offset;
134 dest = FBInfo->Framebuffer;
135 LOG("dest = %p", dest);
136 dest += y * giVT_CharHeight * FBInfo->Pitch;
137 LOG("dest = %p", dest);
139 for( i = 0; i < Length; i++ )
141 if( y >= heightInChars )
143 Log_Notice("DrvUtil", "Stopped at %i", i);
147 // LOG("chars->Ch=0x%x,chars->BGCol=0x%x,chars->FGCol=0x%x",
148 // chars->Ch, chars->BGCol, chars->FGCol);
152 dest + x*giVT_CharWidth*bytes_per_px, FBInfo->Depth, FBInfo->Pitch,
153 VT_Colour12toN(chars->BGCol, FBInfo->Depth),
154 VT_Colour12toN(chars->FGCol, FBInfo->Depth)
159 if( x >= widthInChars )
163 dest += FBInfo->Pitch*giVT_CharHeight;
164 LOG("dest = %p", dest);
167 Length = i * sizeof(tVT_Char);
171 case VIDEO_BUFFMT_FRAMEBUFFER:
172 if(FBInfo->Width*FBInfo->Height*4 < Offset+Length)
174 Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Framebuffer Overflow");
178 //TODO: Handle non 32-bpp framebuffer modes
179 if( FBInfo->Depth != 32 ) {
180 Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Don't support non 32-bpp FB mode");
185 //TODO: Handle pitch != Width*BytesPerPixel
186 // Copy to Frambuffer
187 dest = (Uint8 *)FBInfo->Framebuffer + Offset;
188 memcpy(dest, Buffer, Length);
191 case VIDEO_BUFFMT_2DSTREAM:
192 Length = DrvUtil_Video_2DStream(
193 FBInfo, Buffer, Length,
194 &gDrvUtil_Stub_2DFunctions, sizeof(gDrvUtil_Stub_2DFunctions)
206 void DrvUtil_Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)
208 tDrvUtil_Video_BufInfo *FBInfo = Ent;
210 // TODO: Handle non-32bit modes
211 if( FBInfo->Depth != 32 ) return;
213 // TODO: Be less hacky
214 int pitch = FBInfo->Pitch/4;
215 Uint32 *buf = (Uint32*)FBInfo->Framebuffer + Y*pitch + X;
220 for(i=W;i--;tmp++) *tmp = Colour;
225 void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)
227 tDrvUtil_Video_BufInfo *FBInfo = Ent;
228 int scrnpitch = FBInfo->Pitch;
229 int bytes_per_px = (FBInfo->Depth + 7) / 8;
230 int dst = DstY*scrnpitch + DstX;
231 int src = SrcY*scrnpitch + SrcX;
234 //Log("Vesa_2D_Blit: (Ent=%p, DstX=%i, DstY=%i, SrcX=%i, SrcY=%i, W=%i, H=%i)",
235 // Ent, DstX, DstY, SrcX, SrcY, W, H);
237 if(SrcX + W > FBInfo->Width) W = FBInfo->Width - SrcX;
238 if(DstX + W > FBInfo->Width) W = FBInfo->Width - DstX;
239 if(SrcY + H > FBInfo->Height) H = FBInfo->Height - SrcY;
240 if(DstY + H > FBInfo->Height) H = FBInfo->Height - DstY;
242 //Debug("W = %i, H = %i", W, H);
251 tmp = W*bytes_per_px;
252 for( tmp = W; tmp --; ) {
253 *((Uint8*)FBInfo->Framebuffer + dst + tmp) = *((Uint8*)FBInfo->Framebuffer + src + tmp);
260 memcpy((Uint8*)FBInfo->Framebuffer + dst, (Uint8*)FBInfo->Framebuffer + src, W*bytes_per_px);
265 //Log("Vesa_2D_Blit: RETURN");
269 // --- Disk Driver Helpers ---
270 Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
271 tDrvUtil_Callback ReadBlocks, Uint64 BlockSize, Uint Argument)
273 Uint8 tmp[BlockSize]; // C99
274 Uint64 block = Start / BlockSize;
275 int offset = Start - block * BlockSize;
276 int leading = BlockSize - offset;
281 ENTER("XStart XLength pBuffer pReadBlocks XBlockSize xArgument",
282 Start, Length, Buffer, ReadBlocks, BlockSize, Argument);
284 // Non aligned start, let's fix that!
287 if(leading > Length) leading = Length;
288 LOG("Reading %i bytes from Block1+%i", leading, offset);
289 ret = ReadBlocks(block, 1, tmp, Argument);
294 memcpy( Buffer, &tmp[offset], leading );
296 if(leading == Length) {
301 Buffer = (Uint8*)Buffer + leading;
303 num = ( Length - leading ) / BlockSize;
304 tailings = Length - num * BlockSize - leading;
307 num = Length / BlockSize;
308 tailings = Length % BlockSize;
311 // Read central blocks
314 LOG("Reading %i blocks", num);
315 ret = ReadBlocks(block, num, Buffer, Argument);
317 LEAVE('X', leading + ret * BlockSize);
318 return leading + ret * BlockSize;
322 // Read last tailing block
325 LOG("Reading %i bytes from last block", tailings);
327 Buffer = (Uint8*)Buffer + num * BlockSize;
328 ret = ReadBlocks(block, 1, tmp, Argument);
330 LEAVE('X', leading + num * BlockSize);
331 return leading + num * BlockSize;
333 memcpy( Buffer, tmp, tailings );
340 Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, void *Buffer,
341 tDrvUtil_Callback ReadBlocks, tDrvUtil_Callback WriteBlocks,
342 Uint64 BlockSize, Uint Argument)
344 Uint8 tmp[BlockSize]; // C99
345 Uint64 block = Start / BlockSize;
346 int offset = Start - block * BlockSize;
347 int leading = BlockSize - offset;
352 ENTER("XStart XLength pBuffer pReadBlocks pWriteBlocks XBlockSize xArgument",
353 Start, Length, Buffer, ReadBlocks, WriteBlocks, BlockSize, Argument);
355 // Non aligned start, let's fix that!
358 if(leading > Length) leading = Length;
359 LOG("Writing %i bytes to Block1+%i", leading, offset);
360 // Read a copy of the block
361 ret = ReadBlocks(block, 1, tmp, Argument);
367 memcpy( &tmp[offset], Buffer, leading );
369 ret = WriteBlocks(block, 1, tmp, Argument);
375 if(leading == Length) {
380 Buffer = (Uint8*)Buffer + leading;
382 num = ( Length - leading ) / BlockSize;
383 tailings = Length - num * BlockSize - leading;
386 num = Length / BlockSize;
387 tailings = Length % BlockSize;
390 // Read central blocks
393 LOG("Writing %i blocks", num);
394 ret = WriteBlocks(block, num, Buffer, Argument);
396 LEAVE('X', leading + ret * BlockSize);
397 return leading + ret * BlockSize;
401 // Read last tailing block
404 LOG("Writing %i bytes to last block", tailings);
406 Buffer = (Uint8*)Buffer + num * BlockSize;
408 ret = ReadBlocks(block, 1, tmp, Argument);
410 LEAVE('X', leading + num * BlockSize);
411 return leading + num * BlockSize;
414 memcpy( tmp, Buffer, tailings );
416 ret = WriteBlocks(block, 1, tmp, Argument);
418 LEAVE('X', leading + num * BlockSize);
419 return leading + num * BlockSize;