| View previous topic :: View next topic |
| Author |
Message |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Sun Jun 19, 2005 7:04 am Post subject: 3D on the PSP |
|
|
Ok, I've started digging into sceGu a bit, to see how easy it would be to get something useful, and from the look of it this library is very lowlevel and nice. :)
So, as I'm doing this I'm curious if anyone else is doing this, and perhaps that we should collaborate our efforts? Getting a true 3D-library on the PSP would be a great gain, and as it won't in itself allow anyone to crack games, I'm all for doing some work on it.
From what I've discovered the PSP-graphicscircuit executes lists of commands, much like the GS on PS2 does. The command-format is (command << 24)|(argument), which gives us 24 bits to play with. Floats are also passed this way, using a small wrapper:
| Code: |
void sendCommandf(u8 cmd, float argument)
{
sendCommandi(cmd,(*((u32*)&argument)) >> 8);
}
|
So finally a PlayStation has float-precision. :)
The wrapper-library is as I said very lowlevel and most of it maps 1:1 to the underlying hardware. Example:
| Code: |
void sceGuAmbientColor(u32 color)
{
sendCommandi(85,color & 0xffffff);
sendCommandi(88,color >> 24);
}
|
and sendCommandi() only does this:
| Code: |
void sendCommandi(u8 cmd, u32 argument)
{
u32* gu_struct = *((u32*)0x527a78); // base context?
u32* current = *(gu_struct+1); // get current list pointer
*(current++) = (cmd << 24) | (argument & 0xffffff);
*(gu_struct+1) = current; // store back
}
|
This is later on kicked through sceGuSendList() to the hardware (which calls sceGeListEnQueue() in the kernel), so we won't have to deal with any lowlevel DMAC this time around. Thank you Sony. :)
I've rewritten 20 functions in C so far, and when I get closer to usability I'll submit to the repository. |
|
| Back to top |
|
 |
ooPo Site Admin
Joined: 17 Jan 2004 Posts: 2032 Location: Canada
|
Posted: Sun Jun 19, 2005 7:09 am Post subject: |
|
|
Nice work so far, I just have a question...
| Quote: | void sendCommandf(u8 cmd, float argument)
{
sendCommandi(cmd,(*((u32*)&argument)) >> 8);
} |
Wouldn't that munge the float data? |
|
| Back to top |
|
 |
ooPo Site Admin
Joined: 17 Jan 2004 Posts: 2032 Location: Canada
|
Posted: Sun Jun 19, 2005 7:14 am Post subject: |
|
|
| Also, sendCommandi() seems to be just a list/packet building function. Is the gu_struct supplied by the program, or is it a memory-mapped part of the GU? It looks like sceGeListEnQueue() is just a fancy function that does dma for you by sending your freshly created list to whatever is the local GIF-equivalent. |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Sun Jun 19, 2005 7:20 am Post subject: |
|
|
| ooPo wrote: | Nice work so far, I just have a question...
| Quote: | void sendCommandf(u8 cmd, float argument)
{
sendCommandi(cmd,(*((u32*)&argument)) >> 8);
} |
Wouldn't that munge the float data? |
It would cut down the mantissa from 23 to 15 bits, but the float would still be valid from the hardware POV, as it eats 24-bit floats. You'll only loose some precision doing this.
A normal float has: s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
While the floats here are: s eeeeeeee mmmmmmmmmmmmmmm
And you compute the float as: (+/-) 1.mantissa * pow(2,exponent) so you're only losing the least significant bits. |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Sun Jun 19, 2005 7:22 am Post subject: |
|
|
| ooPo wrote: | | Also, sendCommandi() seems to be just a list/packet building function. Is the gu_struct supplied by the program, or is it a memory-mapped part of the GU? It looks like sceGeListEnQueue() is just a fancy function that does dma for you by sending your freshly created list to whatever is the local GIF-equivalent. |
Most probably, yes, it should probably be called gu_struct or something. :) The PSP probably shares a lot of logic with the PS2, but this time around you(the developer) doesn't have to get your hands dirty with dma-controllers just to display some fancy graphics. |
|
| Back to top |
|
 |
ooPo Site Admin
Joined: 17 Jan 2004 Posts: 2032 Location: Canada
|
Posted: Sun Jun 19, 2005 7:34 am Post subject: |
|
|
| Quote: | A normal float has: s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
While the floats here are: s eeeeeeee mmmmmmmmmmmmmmm |
I wasn't sure of the actual bit structure of a float... it is totally clear now.
And dma is fun, dammit! :) |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Sun Jun 19, 2005 7:40 am Post subject: |
|
|
| ooPo wrote: | | And dma is fun, dammit! :) |
Yep, and it IS simple, but when you get into trouble with the DMA it can be a nasty fellow that some people just can't cope with. Wusses :) |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Sun Jun 19, 2005 11:05 pm Post subject: |
|
|
PSP GE COMMAND LIST
-------------------
Every GE command consists of two parts: The command and the argument. They are assembled like this:
(cmd << 24)|(argument)
The command is 8 bits, and the argument 24-bits.
The GE accepts 24-bit floats. To convert from a standard float, do this:
u32 ge_float = (*((u32*)&normal_float)) >> 8;
This list is very incomplete and might also be incorrect, but I'm working on it.
| Code: |
DEC HEX Description
--- --- -----------
1 01 Vertex list(???)
2 02 Index list(???)
7 07 Index count
16 10 This register seems to be used in a lot of places as HI-bits for pointers...
18 12 Primitive type
Bits 0-23: Type
If the GE inherits from the GS, these should be the primitive types:
0: Points
1: Lines
2: Linestrip
3: Triangles
4: Tristrip
5: Trifan
6: Sprite
This must be verified!!!
42 2A Bone Matrix Offset
Bits 0-23: Bone Matrix offset (index * (4*3)) (4*3 matrix)
43 2B Bone Matrix Value
Bits 0-23: Bone Matrix Value (float)
Written 4*3 times to upload one matrix
44 2C Morph Weight 0
...
45+ 2D+ Morph Weight N... (Don't know how many there can be) (Maximum of 10)
Bits 0-23: Morph Weight (float)
54 36 Patch Divide
Bits 0-7: a0
Bits 8-15: a1
55 37 Patch Prim
Bits 0-1: a0 == 0 : 2; a0 == 2: 1; a0 == 4: 0
56 38 Patch Front Face
Bits 0-23: Value
58 3A Unknown matrix strobe?
Bits: 0-23: Float (strobe???) (write 0.0f before uploading)
59 3B Unknown matrix upload?
Bits: 0-23: Float (write 3*4 values to upload complete matrix) (last column of 4*4 ignored)
60 3C View Matrix strobe?
Bits: 0-23: Float (strobe???) (write 0.0f before uploading)
61 3D View Matrix upload?
Bits: 0-23: Float (write 3*4 values to upload complete matrix) (last column of 4*4 ignored)
62 3E Projection matrix strobe?
Bits 0-23: Float (strobe???) (write 0.0f before uploading)
63 3F Projection Matrix upload?
Bits 0-23: Float (write 4*4 values to upload complete matrix)
64 40 Unknown matrix strobe?
Bits 0-23: Float (strobe???) (write 0.0f before uploading)
65 41 Unknown matrix upload?
Bits: 0-23: Float (write 3*4 values to upload complete matrix) (last column of 4*4 ignored)
66 42 Viewport
Bits: 0-23: Float (Width/Height? X? Y?)
67 43 Viewport
Bits: 0-23: Float (Width/Height? X? Y?)
69 45 Viewport
Bits: 0-23: Float (Width/Height? X? Y?)
70 46 Viewport
Bits: 0-23: Float (Width/Height? X? Y?)
72 48 Texture Scale U
Bits 0-23: U Scale (float)
73 49 Texture Scale V
Bits 0-23: V Scale (float)
74 50 Texture Offset U
Bits 0-23: U Offset (float)
75 51 Texture Offset V
Bits 0-23: V Offset (float)
76 4C Viewport offset (X)
Bits 0-23: X-Offset << 4
77 4D Viewport offset (Y)
Bits 0-23: Y-Offset << 4
80 50 Shading
Bit 0: 0/1 Flat/Gouraud(???)
83 53 Color Material
Bits 0-23: Color Material (RGB?)
84 54 Related to Model Color
Bits 0-23: a0 (sceGuModelColor())
85 55 Related to Model Color / Used in sceGuAmbientColor()
Bits 0-23: a1 (sceGuModelColor())
Bits 0-23: Ambient Color RGB (sceGuAmbientColor())
86 56 Related to Model Color
Bits 0-23: a2 (sceGuModelColor())
87 57 Related to Model Color
Bits 0-23: a3 (sceGuModelColor())
88 58 Ambient Color Alpha
Bits 0-7: Ambient Color Alpha
91 5B Specular Power
Bits 0-23: Specular power (float)
92 5C Ambient RGB (BGR?)
Bits: 0-23: Color
93 5D Ambient Alpha
Bits 0-7: Alpha
155 9B Front Face
Bit 0: 0/1 (Front face???)
160 A0 Texture Base Pointer (Mipmap level 0)
...
167 A7 Texture Base Pointer (Mipmap level 6)
Bits 0-23: Texture Pointer (Local to vram???)
168 A8 Texture Buffer Width (Mipmap level 0)
...
175 AF Texture Buffer Width (Mipmap level 6)
Bits 0-23: Buffer Width (???)
176 B0 CLUT Pointer
Bits 0-23: Clut Address
177 B1 CLUT Pointer (HI)
Bits 16-20: Clut Address (Bits 24-27)
178 B2 Texture Buffer Pointer (Source? Dest?) (sceGuCopyImage())
Bits 0-23: Pointer
179 B3 HI Pointer bits + ??? (t1)
Bits 16-23: HI Pointer bits for Texture Buffer Pointer
Bits 0-15(7?): t1
180 B4 Texture Buffer Pointer 2 (Source? Dest?) (sceGuCopyImage())
Bits 0-23: Pointer
181 B5 HI Pointer bits + ??? (stack1)
Bits 16-23: HI Pointer bits for Texture Buffer Pointer 2
Bits 0-15(7?): t2
184 B8 Texture Size (Mipmap level 0)
...
191 BF Texture Size (Mipmap level 6)
Bits 0-7: Log2(Width)
Bits 8-15: Log2(Height)
192 C0 Texture Projection Map Mode + Texture Map Mode
Bits 0-1: Texture Map Mode
Bits 8-11: Texture Projection Map Mode
193 C1 Texture Map Mode (continued)
Bits 0-1: a1
Bits 8-15(23?): a2
194 C2 Texture Mode
Bits 0-8: a3
Bits 8-15: a2
Bits 16-23: a1
195 C3 Texture Mode (continued)
Bits 0-23: a0
196 C4 Related to CLUT (Number of colors???)
Bits 0-23: ???
197 C5 Clut Mode
Bits 0-1: a0
Bits 2-7(?): a1
Bits 8-15: a2
Bits 16-23: a3
198 C6 Texture Filter
Bits 0-7: a0 (min/mag?)
Bits 8-15: a1 (min/mag?)
199 C7 Texture Wrap
Bits 0-7: U Wrap
Bits 8-15: V Wrap
200 C8 Texture Level Mode (L/K???)
Bits 0-15: a0
Bits 16-23: -128 - 128 (Mip map bias?)
201 C9 Texture Function
Bits 0-7: a0
Bits 8-15: a1
Bits 16-23: ???
202 CA Texture Env Color
Bits 0-23: Color (RGB)
203 CB Texture Flush
Bits 0-23: Strobe? (float) (Just write zero)
204 CC Texture Sync
Bits 0-23: Strobe? (Just write zero)
208 D0 Texture Slope
Bits 0-23: Texture Slope (float)
212 D4 Scissor X/Y Start
Bits 0-9: X Start
Bits 10-19: Y Start
213 D5 Scissor X/Y End
Bits 0-9: X End ((Width + X Start)-1)
Bits 10-19: Y End ((Height + Y Start)-1)
216 D8 Color Function
Bits 0-1: Function
217 D9 Color for Color Function
Bits 0-23: RGB
218 DA Color for Color function (???)
Bits 0-23: RGB
219 DB Alpha Func
Bits 0-7: a0
Bits 8-15: a1
Bits 16-23: a2
220 DC Stencil Function
Bits 0-7: a0
Bits 8-15: a1
Bits 16-23: a2
221 DD Stencil Op
Bits 0-7: a0
Bits 8-15: a1
Bits 16-23: a2
222 DE Depth Function
Bits 0-23(?): Depth test function?
223 DF Blend function
Bits 0-3: a1
Bits 4-7: a2
Bits 8-11: a3
224 E0 Related to blend function
Bits 0-23: Value (fix?)
225 E1 Related to blend function
Bits 0-23: Value (fix?)
226 E2 Dither Matrix, Row 0
...
229 E5 Dither Matrix, Row 3
Bits 0-3: Column 0
Bits 4-7: Column 1
Bits 8-11: Column 2
Bits 12-15: Column 3
230 E6 Logical Op
Bits 0-3: Logical Op
231 E7 Depth Mask
Bits 0-23: Depth Mask
232 E8 Pixel Mask (RGB)
Bits 0-23: Pixel Mask (RGB)
233 E9 Pixel Mask (Alpha)
Bits 0-7: Pixel Mask (Alpha)
234 EA Texture Transfer Mode???
Bit 0: 1/0 (???)
235 EB X/Y Offset for Image copy? (Source/Dest?)
Bits 0-9: X Offset?
Bits 10-19: Y Offset?
236 EC X/Y Offset for Image copy? (Source/Dest?) (2)
Bits 0-9: X Offset?
Bits 10-19: Y Offset?
238 EE Width/Height for texture transfer?
Bits 0-9: Width? (Width-1)
Bits 10-19: Height? (Height-1)
|
Edit #1 (2005-06-19): Added more registers to the list and corrected some errors. |
|
| Back to top |
|
 |
Warren
Joined: 24 Jan 2004 Posts: 173 Location: San Diego, CA
|
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Wed Jun 22, 2005 8:28 am Post subject: |
|
|
Damn, you beat me to updating my own post. :P |
|
| Back to top |
|
 |
Neu
Joined: 16 Jun 2005 Posts: 3
|
Posted: Fri Jun 24, 2005 7:02 pm Post subject: |
|
|
Hi, Chp. I've been working on this too!
I'm wondering how far you got as to using the Enqueue function?
I've been looking through the PuzzleBobble code to see how it uses the gpu as well and made a lot of discoveries.
In the beginning code you can see it send a draw list located at 0x306a4, which is clearly initializing the gpu. The end codes for the list appear to be 0x0F 000000, 0x0C 000000.
I can send this same list to the gpu as well. On the new PSP-Tool Chain, when I call list Enqueue, nothing seems to happen. I verified this by sending random commands. However on the ps2-tool chain sending random commands crashes the psp. (To Check that List is actually being used)
I get a nice zero returned from DrawSync() and ListSync(), and ListEnQueue returns some kind of ID value.
I was just wondering what your startup.s looks like because if I use the stub info from the online api docs its:
STUB_START "sceGe_driver",0x40010000,0x00150005
STUB_FUNC 0xab49e76a,sceGeListEnQueue
STUB_FUNC 0x1c0d95a6,sceGeListEnQueueHead
STUB_END
which is different than: (posted on here originally)
STUB_START "sceGe_user",0x40010000,0x000A0005
STUB_FUNC 0xAB49E76A,sceGeListEnQueue
STUB_FUNC 0x1C0D95A6,sceGeListEnQueueHead
STUB_END
I really dont know much about how the stubbing works, so if this is a stupid question please forgive me. |
|
| Back to top |
|
 |
Treat
Joined: 26 Sep 2004 Posts: 16
|
Posted: Fri Jun 24, 2005 10:12 pm Post subject: |
|
|
i think the high word of the second number should correspond to the number of stub functions i.e
STUB_START "sceGe_driver",0x40010000,0x00020005
STUB_FUNC 0xab49e76a,sceGeListEnQueue
STUB_FUNC 0x1c0d95a6,sceGeListEnQueueHead
STUB_END
don't know if that makes any difference |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Sat Jun 25, 2005 10:31 am Post subject: |
|
|
| Neu wrote: | Hi, Chp. I've been working on this too!
I'm wondering how far you got as to using the Enqueue function?
|
I've figured out how to use the sceGeListEnQueue(), but I've been more focused on getting a complete picture on how the hardware works with a full reverse of all involved code before I start to experiment how to use it. This way I won't have to second-guess what I'm doing. I'll probably give it a proper go this weekend.
I'll get back with some results soon (and with full sources of course :) ).
To give some help on the road:
int sceGeListEnQueue(void* start, void* stall, int id, int unknown);
start is which list that is to be enqueued for a transfer.
stall is where the transfer should stall (so that you can enqueue a list and then keep updating the stall-address using sceGuUpdateStallAddr()). Passing 0 to this address executes the list. If you look at the rest of the code for sceGu, you'll see that the address is updated in several locations, as long as the first context is active.
id is the kernel callback id previously registered. (look at sceGuInit())
I've not yet looked at the last unknown, as it hasn't beeen used except in sceGuSendList(). What is passed in there seems to be some kind of array (2 dwords, first one a size and then some data-pointer that I haven't looked at yet)
The value returned is the id for the enqueued list. You use this id when referring to it in other sceGe-functions. |
|
| Back to top |
|
 |
Neu
Joined: 16 Jun 2005 Posts: 3
|
Posted: Mon Jun 27, 2005 6:49 am Post subject: |
|
|
Hey thanks for the help.
I've been looking at the disasm a lot, one question I have is:
If sceGu is supposed to be a static linked lib, then why does it access memory at 0x52XXXX ? It seems like a lot of the puzzle bubble globals are stored in that address range, but the gpu code makes access to that memory all the time.
Have any of you guys started making a memory map for it? I think this would help a lot. I started, but a lot of things I'm not sure of. All the addresses are offsets from 0x520000:
Ex:
globalMem -> 0x52000;
globalMem[31376] = [FrameBufferFormat]
globalMem[31380] = [DrawBuffer Width]
globalMem[31384] = [DrawBufferPtr BaseOffset] = 0x00 (Set to Zero in ResetStatics)
Is my code still gonna work if I don't use these addresses? At first I thought it was just some global vars, because I thought memory mapped addresses need to be a lot higher? But then again they are set explicitly in the sceGu code.
Oh, and does it matter where in memory you store the DrawingList ?
| Quote: | u32* gu_struct = *((u32*)0x527a78); // base context?
|
|
|
| Back to top |
|
 |
ector
Joined: 12 May 2005 Posts: 195
|
Posted: Mon Jun 27, 2005 7:25 am Post subject: |
|
|
Puzzle Bobble (and the other commercial games) are not prerelocated so all those references are wrong.
That said, i'm having strange issues with variables in the 0x0e000000 and 0x00600000 ranges in my emulator but i suspect it's mostly my relocations that are b0rked :P |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Mon Jun 27, 2005 8:56 am Post subject: |
|
|
| Neu wrote: | Hey thanks for the help.
I've been looking at the disasm a lot, one question I have is:
If sceGu is supposed to be a static linked lib, then why does it access memory at 0x52XXXX ? It seems like a lot of the puzzle bubble globals are stored in that address range, but the gpu code makes access to that memory all the time.
Have any of you guys started making a memory map for it? |
Sure. This is my current one, a few left to resolve:
| Code: |
/* 0x527A34 0x52 31284 */
typedef struct
{
void* callbacks[2]; /* 0x527A34, 0x527A38 31284, 31288 */
int unknown2; /* 30292 */
int unknown3; /* 30296 */
int unknown4; /* 31300 */
int unknown5; /* 31304 */
int unknown6; /* 31308 */
int unknown7; /* 31312 */
int unknown8; /* 31316 */
int unknown9; /* 31320 */
int unknown_send_list; /* 0x527A5C 31324 */ /* current list index enqueued??? */
int kernel_event_flag; /* 0x527A60 31328 */
int ge_callback_id; /* 0x527A64 31332 */
/* ... */
} GuSettings;
typedef struct
{
unsigned int* start;
unsigned int* current;
int parent_context;
} gu_display_list;
/* 0x527914 0x52 30996 */
typedef struct
{
gu_display_list list; // 0 4 8
int unknown3; // 12
int scissor_start[2]; // 16 20
int scissor_end[2]; // 24 28
int near_plane; // 32
int far_plane; // 36
int depth_offset; // 40
int unknown11; // 44 used in combination with texture_function
int texture_function; // 48
int texture_proj_map_mode; // 52
int texture_map_mode; // 56
int sprite_mode[4]; // 60 64 68 72
unsigned int clear_color; // 76
unsigned int clear_stencil; // 80
unsigned int clear_depth; // 84
int texture_mode; // 88
} GuContext; // 92 bytes
typedef struct
{
int pixel_size; // 0 0
int frame_width; // 1 4
void* frame_buffer; // 2 8
void* disp_buffer; // 3 12
void* depth_buffer; // 4 16
int depth_width; // 5 20
int width; // 6 24
int height; // 7 28
} GuDrawBuffer;
typedef struct
{
unsigned char row0[4];
unsigned char row1[4];
unsigned char row2[4];
unsigned char row3[4];
} GuLightSettings;
extern unsigned int gu_unknown1; /* 0x527910 30992 */
extern GuContext* gu_contexts; /* 0x527914 30996 */
extern int ge_list_executed[2]; /* 0x527A28 31272, 31276 */
extern void* ge_edram_address; /* 0x527A30 31280 */
extern GuSettings gu_settings; /* 0x527A34 31284 */
extern gu_display_list* gu_list; /* 0x527A78 31352 */
extern int gu_curr_context; /* 0x527A7C 31356 */
extern int gu_init; /* 0x527A80 31360 */
extern int gu_display_on; /* 0x527A84 31364 */
extern int gu_call_mode; /* 0x527A88 31368 */
extern int gu_states; /* 0x527A8C 31372 */
extern GuDrawBuffer gu_draw_buffer; /* 0x527A90 31376, 31380, 31384, 31388, 31392, 31396, 31400 */
/* 31404 */
extern unsigned int** gu_object_stack; /* 0x527AB0 31408 */
extern int gu_object_stack_depth; /* 0x527B30 31536 */
extern GuLightSettings light_settings[4]; /* 0x30A78 2680 */
|
|
|
| Back to top |
|
 |
Darkcreator
Joined: 30 Apr 2005 Posts: 7 Location: Florida
|
Posted: Thu Jun 30, 2005 7:50 am Post subject: |
|
|
thanks alot chp I was gona work on that thxs for doing it for me _________________ whats up ? |
|
| Back to top |
|
 |
ReJ
Joined: 04 Apr 2004 Posts: 25 Location: Lithuania, Vilnius
|
Posted: Sun Jul 03, 2005 12:58 pm Post subject: |
|
|
| Quote: | 234 EA Texture Transfer Mode???
Bit 0: 1/0 (???) |
Actually, it seems to be a size of the pixel ( a0 ^ 0x03 )
0 - 16 bit
1 - 32 bit
( GE_TPSM_5650 | GE_TPSM_5551 | GE_TPSM_4444 ) ^ 0x03 == 0
( GE_TPSM_8888 ) ^ 0x03 == 1
Description of other registers used in sceGuCopyImage() seems to be right (178 source, 179 src_bpw, 235 src_x_y, 238 src_width_height, 180 dest, 181 dest_bpw, 236 dest_x_y ). |
|
| Back to top |
|
 |
yarik
Joined: 26 Sep 2008 Posts: 2
|
Posted: Sat Sep 27, 2008 2:30 am Post subject: |
|
|
| [solved] |
|
| Back to top |
|
 |
Pirata Nervo
Joined: 09 Oct 2007 Posts: 409
|
Posted: Sat Sep 27, 2008 5:29 am Post subject: |
|
|
lol? _________________
Upgrade your PSP |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sat Sep 27, 2008 5:33 am Post subject: |
|
|
| too shameful that you prefer to delete your question ? |
|
| Back to top |
|
 |
yarik
Joined: 26 Sep 2008 Posts: 2
|
Posted: Sun Sep 28, 2008 10:32 pm Post subject: |
|
|
>too shameful that you prefer to delete your question ?
yeah |
|
| Back to top |
|
 |
|