GIF packet questions

Discuss the development of software, tools, libraries and anything else that helps make ps2dev happen.

Moderators: cheriff, Herben

Post Reply
Steve F
Posts: 75
Joined: Wed Apr 27, 2005 2:30 am
Location: Texas USA

GIF packet questions

Post by Steve F »

I just finished manually disassembing the setupscr structure in debug-scr_printf-init_scr. Boy, there is nothing better for learning than doing it the hard way.

My first question is, how can this packet structure be 16 bit aligned and still work when the doc's say GIF packets must be 128 bit aligned?

static struct t_setupscr setupscr __attribute__ (( aligned (16) )) = {
{ 0x100000000000800E, 0xE, 0xA0000, 0x4C, 0x8C, 0x4E },
{ 27648, 30976 },
{ 0x18 },
{ 0, 639, 0, 223 },
{ 0x40, 1, 0x1a, 1, 0x46, 0, 0x45, 0x70000,
0x47, 0x30000, 0x47, 6, 0, 0x3F80000000000000, 1, 0x79006C00, 5,
0x87009400, 5, 0x70000, 0x47 }
};

Next, in the packet and graph library why do we load by u64's?

#define GIF_SET_FRAME(A,B,C,D) \
(u64)((A) & 0x000001FF) << 0 | (u64)((B) & 0x0000003F) << 16 | \
(u64)((C) & 0x0000003F) << 24 | (u64)((D) & 0xFFFFFFFF) << 32

#define GIF_REG_FRAME_1 0x4C // Frame buffer setting. (Context 1)

packet_append_64(&graph_packet, GIF_SET_FRAME(address >> 13, graph_get_width() >> 6, current_psm, 0));
packet_append_64(&graph_packet, GIF_REG_FRAME_1);

Why not:

#define GIF_SET_FRAME_1(A,B,C,D) \
(u64)((A) & 0x000001FF) << 0 | (u64)((B) & 0x0000003F) << 16 | \
(u64)((C) & 0x0000003F) << 24 | (u64)((D) & 0xFFFFFFFF) << 32 | \
(u8)((0x4c) << 64

packet_append_128(&graph_packet, GIF_SET_FRAME_1(address >> 13, graph_get_width() >> 6, current_psm, 0));

And regarding PACKED Mode, how come all the examples are as follows:

// Set up the draw buffer.
packet_append_64(&graph_packet, GIF_SET_TAG(5, 1, 0, 0, GIF_TAG_PACKED, 1));
packet_append_64(&graph_packet, 0x0E);
packet_append_64(&graph_packet, GIF_SET_FRAME(address >> 13, graph_get_width() >> 6, current_psm, 0));
packet_append_64(&graph_packet, GIF_REG_FRAME_1);
packet_append_64(&graph_packet, GIF_SET_SCISSOR(0, graph_get_width() - 1, 0, graph_get_height() - 1));
packet_append_64(&graph_packet, GIF_REG_SCISSOR_1);
packet_append_64(&graph_packet, GIF_SET_TEST(0, 0, 0, 0, 0, 0, 1, 2));
packet_append_64(&graph_packet, GIF_REG_TEST_1);
packet_append_64(&graph_packet, GIF_SET_XYOFFSET((2048 - (graph_get_width() >> 1)) << 4, (2048 - (graph_get_height() >> 1)) << 4));
packet_append_64(&graph_packet, GIF_REG_XYOFFSET_1);
packet_append_64(&graph_packet, GIF_SET_PRMODECONT(1));
packet_append_64(&graph_packet, GIF_REG_PRMODECONT);

Instead of:

// Set up the draw buffer.
packet_append_64(&graph_packet, GIF_SET_TAG(5, 1, 0, 0, GIF_TAG_PACKED, 1));
packet_append_64(&graph_packet, GIF_REG_PRMODECONT|GIF_REG_XYOFFSET_1|GIF_REG_TEST_1|GIF_REG_SCISSOR_1|GIF_REG_FRAME_1);
packet_append_64(&graph_packet, GIF_SET_FRAME(address >> 13, graph_get_width() >> 6, current_psm, 0));
packet_append_64(&graph_packet, GIF_SET_SCISSOR(0, graph_get_width() - 1, 0, graph_get_height() - 1));
packet_append_64(&graph_packet, GIF_SET_TEST(0, 0, 0, 0, 0, 0, 1, 2));
packet_append_64(&graph_packet, GIF_SET_XYOFFSET((2048 - (graph_get_width() >> 1)) << 4, (2048 - (graph_get_height() >> 1)) << 4));
packet_append_64(&graph_packet, GIF_SET_PRMODECONT(1));

Isn't this a better format for conserving memory space and improving transfer speed?

And the last question, with the GIF defines, i.e., GIF_REG_FRAME_1 there is a // comment character followed by the comment. Later in the packet_append the preprocessor symbol is referenced as an argument.

#define GIF_REG_FRAME_1 0x4C // Frame buffer setting. (Context 1)

packet_append_64(&graph_packet, GIF_SET_FRAME(address >> 13, graph_get_width() >> 6, current_psm, 0));
packet_append_64(&graph_packet, GIF_REG_FRAME_1);

Shouldn't this be preprocessed as:

packet_append_64(&graph_packet, 0x4C // Frame buffer setting. (Context 1));

And cause a compiler error?

Mucha apreciación!
ooPo
Site Admin
Posts: 2023
Joined: Sat Jan 17, 2004 9:56 am
Location: Canada
Contact:

Re: GIF packet questions

Post by ooPo »

Steve F wrote:My first question is, how can this packet structure be 16 bit aligned and still work when the doc's say GIF packets must be 128 bit aligned?

static struct t_setupscr setupscr __attribute__ (( aligned (16) )) = {
The alignment is specified in bytes, 16 bytes = 128 bits.
Steve F wrote:Next, in the packet and graph library why do we load by u64's?

#define GIF_SET_FRAME(A,B,C,D) \
(u64)((A) & 0x000001FF) << 0 | (u64)((B) & 0x0000003F) << 16 | \
(u64)((C) & 0x0000003F) << 24 | (u64)((D) & 0xFFFFFFFF) << 32
Using 64 bits is easier than the crazy, hacked-in 128-bit support we have. As well, most registers in the PS2 are either 64 or 32 bits in size... casting into a u64 avoids compiler errors about shifting past a variable's bit size.
Steve F wrote:And regarding PACKED Mode, how come all the examples are as follows:

// Set up the draw buffer.
packet_append_64(&graph_packet, GIF_SET_TAG(5, 1, 0, 0, GIF_TAG_PACKED, 1));
packet_append_64(&graph_packet, 0x0E);
packet_append_64(&graph_packet, GIF_SET_FRAME(address >> 13, graph_get_width() >> 6, current_psm, 0));
packet_append_64(&graph_packet, GIF_REG_FRAME_1);
packet_append_64(&graph_packet, GIF_SET_SCISSOR(0, graph_get_width() - 1, 0, graph_get_height() - 1));
packet_append_64(&graph_packet, GIF_REG_SCISSOR_1);
packet_append_64(&graph_packet, GIF_SET_TEST(0, 0, 0, 0, 0, 0, 1, 2));
packet_append_64(&graph_packet, GIF_REG_TEST_1);
packet_append_64(&graph_packet, GIF_SET_XYOFFSET((2048 - (graph_get_width() >> 1)) << 4, (2048 - (graph_get_height() >> 1)) << 4));
packet_append_64(&graph_packet, GIF_REG_XYOFFSET_1);
packet_append_64(&graph_packet, GIF_SET_PRMODECONT(1));
packet_append_64(&graph_packet, GIF_REG_PRMODECONT);

Instead of:

// Set up the draw buffer.
packet_append_64(&graph_packet, GIF_SET_TAG(5, 1, 0, 0, GIF_TAG_PACKED, 1));
packet_append_64(&graph_packet, GIF_REG_PRMODECONT|GIF_REG_XYOFFSET_1|GIF_REG_TEST_1|GIF_REG_SCISSOR_1|GIF_REG_FRAME_1);
packet_append_64(&graph_packet, GIF_SET_FRAME(address >> 13, graph_get_width() >> 6, current_psm, 0));
packet_append_64(&graph_packet, GIF_SET_SCISSOR(0, graph_get_width() - 1, 0, graph_get_height() - 1));
packet_append_64(&graph_packet, GIF_SET_TEST(0, 0, 0, 0, 0, 0, 1, 2));
packet_append_64(&graph_packet, GIF_SET_XYOFFSET((2048 - (graph_get_width() >> 1)) << 4, (2048 - (graph_get_height() >> 1)) << 4));
packet_append_64(&graph_packet, GIF_SET_PRMODECONT(1));

Isn't this a better format for conserving memory space and improving transfer speed?
You are absolutely correct. Congrats. :)

However, for operations that only get called once or twice per frame it really doesn't matter for speed. However, readability increases when you spread it out like that in AD mode.

Remember also that the code in ps2sdk isn't supposed to be the fastest and most optimized code available, at least for the packet and graph code... it is designed to be an example for a new user to work from.
Steve F wrote:And the last question, with the GIF defines, i.e., GIF_REG_FRAME_1 there is a // comment character followed by the comment. Later in the packet_append the preprocessor symbol is referenced as an argument.

#define GIF_REG_FRAME_1 0x4C // Frame buffer setting. (Context 1)

packet_append_64(&graph_packet, GIF_SET_FRAME(address >> 13, graph_get_width() >> 6, current_psm, 0));
packet_append_64(&graph_packet, GIF_REG_FRAME_1);

Shouldn't this be preprocessed as:

packet_append_64(&graph_packet, 0x4C // Frame buffer setting. (Context 1));

And cause a compiler error?
Nope, the comment is stripped off before it gets inserted into the various parts of the code.
Steve F
Posts: 75
Joined: Wed Apr 27, 2005 2:30 am
Location: Texas USA

Post by Steve F »

Thank you ooPo. I was hoping this would be the peak of the learning curve and it would get easier from here. I'm so naive sometimes.

I'm looking at the video initialization in scr_printf-debug. I understand the part SetGsCrt is doing for the output circuits and setting up the frame and z buffer using GIFTAG dma for the [input] drawing functions.

There is an asm routine called SetVideoMode. I don't understand what it is doing there. The latest libraries and examples don't have any equivalent. Nothing turns up searching these forums. A Google search returns references to PS1 development. There is a knowledge base article (kb.x?T=249) but no usage information except it seems that someone named Duke was instrumental in early Playstation software development.
ooPo
Site Admin
Posts: 2023
Joined: Sat Jan 17, 2004 9:56 am
Location: Canada
Contact:

Post by ooPo »

You mean this?

Code: Select all

static void SetVideoMode&#40;&#41;
&#123;
  unsigned dma_addr;
  unsigned val1;
  unsigned val2;
  unsigned val3;
  unsigned val4;
  unsigned val4_lo;

  asm volatile &#40;"        .set push               \n"
                "        .set noreorder          \n"
                "        lui     %4, 0x000d      \n"
                "        lui     %5, 0x0182      \n"
                "        lui     %0, 0x1200      \n"
                "        li      %2, 2           \n"
                "        ori     %4, %4, 0xf9ff  \n"
                "        ori     %5, %5, 0x4290  \n"
                "        li      %1, 0xff62      \n"
                "        dsll32  %4, %4, 0       \n"
                "        li      %3, 0x1400      \n"
                "        sd      %1, 0&#40;%0&#41;       \n"
                "        or      %4, %4, %5      \n"
                "        sd      %2, 0x20&#40;%0&#41;    \n"
                "        sd      %3, 0x90&#40;%0&#41;    \n"
                "        sd      %4, 0xa0&#40;%0&#41;    \n"
                "        .set pop                \n"
                &#58; "=&r" &#40;dma_addr&#41;, "=&r" &#40;val1&#41;, "=&r" &#40;val2&#41;,
                "=&r" &#40;val3&#41;, "=&r" &#40;val4&#41;, "=&r" &#40;val4_lo&#41; &#41;;
&#125;
I have no idea what it is doing. :)
Steve F
Posts: 75
Joined: Wed Apr 27, 2005 2:30 am
Location: Texas USA

Post by Steve F »

Yep, that's the one. I'll make a clean test program tomorrow and see what happens when I delete it. I have a guess it might be an asm equivalent of:

GS_REG_DISPFB1 = GS_SET_DISPFB(address >> 13, graph_get_width() >> 6, current_psm, 0, 0);

from sdk graph.c .

I haven't been able to tell from the doc's if directly setting GS_REG_DISPFB1 is also accomplished with GIFTAG setup of the frame buffer. If that is the case, one of them is redundent?
Steve F
Posts: 75
Joined: Wed Apr 27, 2005 2:30 am
Location: Texas USA

Post by Steve F »

I figured out what SetVideoMode in libdebug/scr_printf is doing. I rewrote the inline so it makes more sense.

Code: Select all

asm volatile &#40;
".set push             \n"
".set noreorder        \n"
"lui    %0, 0x1200     \n" // %0 = dma_addr = base of GS regs = 0x12000000
"li     %1, 0xff62     \n"
"sd     %1, 0&#40;%0&#41;      \n" // %1 = val1 = PMODE = 0xff62
"li     %2, 2          \n"
"sd     %2, 0x20&#40;%0&#41;   \n" // %2 = val2 = SMODE2 0x02
"li     %3, 0x1400     \n"
"sd     %3, 0x90&#40;%0&#41;   \n" // %3 = val3 = GS_REG_DISPFB2 = 0x1400 
"lui    %4, 0x000d     \n"
"ori    %4, %4, 0xf9ff \n"
"dsll32 %4, %4, 0      \n"
"lui    %5, 0x0182     \n"
"ori    %5, %5, 0x4290 \n"
"or     %4, %4, %5     \n"
"sd     %4, 0xa0&#40;%0&#41;   \n" // %4 = val4 = GS_REG_DISPLAY2 = 0x000df9ff01824290
".set pop              \n"
&#58; "=&r" &#40;dma_addr&#41;, "=&r" &#40;val1&#41;, "=&r" &#40;val2&#41;,
  "=&r" &#40;val3&#41;, "=&r" &#40;val4&#41;, "=&r" &#40;val4_lo&#41;
&#41;;
This can be replaced by

Code: Select all

GS_REG_PMODE = GS_SET_PMODE&#40;0, 1, 1, 1, 0, 255&#41;;
GS_REG_SMODE2 = GS_SET_SMODE2&#40;0, 1, 0&#41;;
GS_REG_DISPFB2 = GS_SET_DISPFB&#40;0 >> 13, 640 >> 6, 0, 0, 0&#41;; 
GS_REG_DISPLAY2 = GS_SET_DISPLAY&#40;656, 36, 3, 0, 2559,  223&#41;;
An interesting discovery is that scr_printf uses read output circuit 2 and turns circuit 1 off.

For my own uses, I am adding a mode argument to init_scr so I can switch between PAL, NTSC, VGA (all resolutions), and HDTV in my ps2link loader. I will probably add a configuration argument to IPCONFIG.DAT to set the video mode. Without a setting in IPCONFIG.DAT it will default to GS_TV_AUTO which uses the expresion (((*((char*)0x1FC7FF52))=='E')+2) to figure out if it's a PAL or NTSC console.

Are these changes a good candidate for updating the debug module in CVS?
ooPo
Site Admin
Posts: 2023
Joined: Sat Jan 17, 2004 9:56 am
Location: Canada
Contact:

Post by ooPo »

I'd welcome the changes, but those parts of ps2sdk are closely watched by the old guard. You'll have to run it by them first. :)

But if it doesn't add bloat and doesn't change the default behaviour... chances are it'll be fine.
Post Reply