Jump to content
Luigi301

jaglib and DSP program offsets

Recommended Posts

I have this program containing some matrix math functions for the DSP that I'm working on. I want to be able to load the whole thing into DSP memory once and run the individual snippets that I need. How do I calculate the offset I need to point jag_dsp_go() to in order to call an individual snippet?

 

I want to be able to do:

#define DSP_FUNCTION_LOAD(X) jag_dsp_load(D_RAM, X, X ## _end - X );
#define DSP_FUNCTION_GO(X) jag_dsp_go((uint32_t *)X, 0);

/* here's what I need to figure out, this is wrong */
#define DSP_FUNCTION_OFFSET(X) ( (uint32_t *)(0xF1B000 + (dsp_matrix_functions_end - X)) ) 
 
jag_dsp_load(D_RAM, dsp_matrix_functions, dsp_matrix_functions_end-dsp_matrix_functions);
jag_dsp_go(DSP_FUNCTION_OFFSET(dsp_matrix_add), 0);

But I don't know how to calculate the starting address for dsp_matrix_add.

Edited by Luigi301

Share this post


Link to post
Share on other sites

I solved my problem. In my case, the solution was:

void DSP_START(uint8_t *function) {
  uint32_t calculated_pc = 0xF1B000 + (uint32_t)(function - dsp_matrix_functions);
 
  MMIO32(D_PC) = calculated_pc;
  printf("DSP running from 0x%08X\n", calculated_pc);
  MMIO32(D_CTRL) = MMIO32(0xF1A114) | 0x01;
}

Where dsp_matrix_functions is the start of the program code in DSP RAM and *function is a pointer to the function I want. D_PC just needed to be set to the offset in DSP RAM. I was trying to make the DSP run the programs out of cartridge ROM above. Now I've got 4x4 matrix addition and subtraction running on the DSP!

Edited by Luigi301
  • Like 2

Share this post


Link to post
Share on other sites

I guess I'll use this thread as a general Jaguar questions thread.

 

I'm working on adding wireframe 3D to my Jag program, currently doing calculations on the CPU. I'm blitting lines to a 320x200 bitmap that gets drawn as the lowest-priority object by the Object Processor. The first thing that my frame loop does is use the blitter to set the contents of the buffer to 0. The problem then is that the bitmap stays blank until around scanline 140 of the screen. Nothing I draw appears above that line, like it's taking that long to get there. The blitter surely doesn't take half the screen to blit 64KB of 0s and the calculations aren't happening until the end of the frame loop, so what am I missing?

 

Here's my frameloop on Github.

Edited by Luigi301

Share this post


Link to post
Share on other sites

I guess I'll use this thread as a general Jaguar questions thread.

 

I'm working on adding wireframe 3D to my Jag program, currently doing calculations on the CPU. I'm blitting lines to a 320x200 bitmap that gets drawn as the lowest-priority object by the Object Processor. The first thing that my frame loop does is use the blitter to set the contents of the buffer to 0. The problem then is that the bitmap stays blank until around scanline 140 of the screen. Nothing I draw appears above that line, like it's taking that long to get there. The blitter surely doesn't take half the screen to blit 64KB of 0s and the calculations aren't happening until the end of the frame loop, so what am I missing?

 

Here's my frameloop on Github.

//clear_video_buffer(); 
jag_memset32(jag_vidmem, 1, (320*200)/4, 0); 
//jag_wait_blitter_ready(); 

Does jag_memset32 use the blitter ?

Share this post


Link to post
Share on other sites

Im not sure, but clear_video_buffer just blits a black 320x200 rectangle to the screen and has the same slowness. Maybe the problem is something else, I'm not sure how the DMA priorities work. It shouldn't be doing anything else other than processing the object list. The GPU and DSP are idle and the object list only contains 3 bitmaps and a stop object.

Edited by Luigi301

Share this post


Link to post
Share on other sites

I played with the blitter settings and I don't think it's the blitter. I don't think I'm synced to vblank. Either that or setting a matrix to identity with the CPU takes 200 scanlines.

 

I can't find the jaglib source code so I'll try writing my own vblank interrupt sync stuff using Breakout 2000's startup code as a reference. I've done all this on the Amiga but the Jaguar's video hardware is... stranger than the Amiga.

Edited by Luigi301

Share this post


Link to post
Share on other sites

The emulator claims it's running at 60fps. I tried putting the blitter in phrase mode (it was running in pixel mode for blitting 320x200, whoops) and it didn't seem to help. Hmm.

Share this post


Link to post
Share on other sites

Yeah, I wired up a simple double-buffering setup and it took care of the issue. I don't know why I didn't think of that. Now I've got... uh, other issues to fix with my rotation logic.

 

xQ5JE7N.gif

Share this post


Link to post
Share on other sites

Okay, it looks like the problem is my line blitting routine. I'm not converting a slope to A1_INC and A1_FINC values right.

 

Draw a line from (0,0) to (64,64) - slope of 1, A1_INC = (1,1), no fraction. Okay.

Draw a line from (0,0) to (32,48) - slope of 0.666... A1_INC = (0,0), A1_FINC = (0.666,0)? Now there's no Y increment... A1_INC.y = 1? 0.666?

Draw a line from (0,0) to (100,10) - slope of 10. A1_INC = (1,10)?

 

Do we increment by X = 1, Y = slope for slopes > 1 and X = slope, Y = 1 for slopes < 1? Do we need A1_STEP at all?

 

I haven't figured out the correlation yet. I can draw all the vertical and horizontal lines I want though. Here's the whole blit routine on Github.

Edited by Luigi301

Share this post


Link to post
Share on other sites

Its too late for me to answer fully but here's some snippets from my raptor basic program for drawing lines.

 

Ignore the blitlist[] array, you aren't using that but the lines below are commented to say which register they are setting. Its not optimised in any way, just a basic drawing function. Sorry about the formatting too. Hopefully this will give you some clues.

 

Here's what all the calls to the blitter are set to;

 

blitlist[0] = gfxroad 'Destination gfx 'A1_BASE
blitlist[1] = PITCH1|PIXEL16|WID64|XADDINC 'Destination Blitter flags 'A1_FLAGS
blitlist[2] = 0 'A1_CLIP
blitlist[3] = (16<<16)+16 'Start Pixel - NOTE: y then x 'A1_PIXEL
blitlist[4] = 0 'A1_STEP_INT
blitlist[5] = 0 'A1_STEP_FRAC
blitlist[6] = 0 'A1_PIXEL_POINTER
blitlist[7] = (0<<16)+1 'A1_INC_INT y, x
blitlist[8] = (32768<<16)+0 'A1_INC_FRACT y, x
blitlist[9] = 0 'A2_BASE
blitlist[10] = 0 'A2_FLAGS
blitlist[11] = 2000 'Colour of pixels to write 'B_PATD
blitlist[12] = 0 'A2_PIXEL
blitlist[13] = 0 'A2_STEP
blitlist[14] = (1<<16)+32 'Number of pixels to write 'B_counter
blitlist[15] = PATDSEL|DSTEN|UPDA1|UPDA1F 'Blitter commands 'B_CMD
And here is the line routine;
SUB DrawLine(x1 as INTEGER, y1 as INTEGER, x2 as INTEGER, y2 as INTEGER)
'Create a line that will ensure dy < dx
x1 = x1<<16
y1 = y1<<16
x2 = x2<<16
y2 = y2<<16
IF x1 > x2 THEN
tx = x2
ty = y2
x2 = x1
y2 = y1
x1 = tx
y1 = ty
ENDIF
dx = x2 - x1
IF y2 > y1 THEN
dy = y2 - y1
ELSE
dy = y1 - y2
ENDIF
IF dy < dx THEN
'mostly horiz
XINC = 1
IF y1 > y2 THEN
YINC = 65536 - ((dy<<16)/dx)
blitlist[7] = (-1<<16)+XINC 'A1_INC_INT y, x
blitlist[8] = (YINC<<16)+0 'A1_INC_FRACT y, x
ELSE
YINC = ((dy<<16)/(dx))
blitlist[7] = (0<<16)+XINC 'A1_INC_INT y, x
blitlist[8] = (YINC<<16)+0 'A1_INC_FRACT y, x
ENDIF
blitlist[3] = (y1)+(x1>>16) 'A1_PIXEL y, x
blitlist[14] = (1<<16)+(dx>>16) 'B_counter y, x
ELSEIF dy > dx THEN
'mostly vert
IF y1 > y2 THEN
YINC = -1
XINC = ((dx<<16)/dy)
blitlist[7] = (YINC<<16)+0 'A1_INC_INT y, x
blitlist[8] = (0<<16)+XINC 'A1_INC_FRACT y, x
ELSE
YINC = 1
XINC = ((dx<<16)/(dy))
blitlist[7] = (YINC<<16)+0 'A1_INC_INT y, x
blitlist[8] = (0<<16)+XINC 'A1_INC_FRACT y, x
ENDIF
blitlist[3] = (y1)+(x1>>16) 'A1_PIXEL y, x
blitlist[14] = (dy)+(1) 'B_counter y, x
ELSEIF dy = dx THEN
'45 degs
IF y1 > y2 THEN
XINC = 1
YINC = -(1<<16)
ELSE
XINC = 1
YINC = (1<<16)
ENDIF
blitlist[3] = (y1)+(x1>>16) 'A1_PIXEL y, x
blitlist[7] = (YINC)+XINC 'A1_INC_INT y, x
blitlist[8] = (0<<16)+0 'A1_INC_FRACT y, x
blitlist[14] = (1<<16)+(dx>>16) 'B_counter y, x
ENDIF
END SUB
Edited by Sporadic

Share this post


Link to post
Share on other sites

That's helpful, thanks! I think I'm on the right track now.

 

e: Yep! Got them drawing in all octants now. I'm thinking the distortions are accuracy problems with doing trigonometry with 16.16 numbers...

 

cCvwTMY.png

Edited by Luigi301
  • Like 2

Share this post


Link to post
Share on other sites

If I have a 1bpp text layer and an 8bpp background layer, can I use the blitter to combine them automatically? i.e. if I set the text layer up as A2 and 1bpp and the background layer as A1 and 8bpp, is it smart enough to expand the 1bpp pixels to 8bpp pixels? I'm not sure if my problem is the blitter not being able to do that or not setting the parameters up right.

Share this post


Link to post
Share on other sites

I went around the problem with a better solution anyway - adding a 1bpp text layer with the object processor instead of combining a 1bpp text layer and an 8bpp background layer. Now I can put text on my screen :D

  • Like 2

Share this post


Link to post
Share on other sites

My Skunkboard and Jag arrived, too. But why does my spinning square, which works on Virtual Jaguar as you can see above, get drawn incorrectly on the real machine? Hmm.

 

test.png

 

Share this post


Link to post
Share on other sites

My Skunkboard and Jag arrived, too. But why does my spinning square, which works on Virtual Jaguar as you can see above, get drawn incorrectly on the real machine? Hmm.

 

Make sure you're setting all the blitter registers every call as some of them are altered as it uses them

  • Like 2

Share this post


Link to post
Share on other sites

Is there a fast way to do transparent blits with the blitter alone? I have some 16x16 sprites I want to blit from a sheet onto a background layer. I dont want to do it with the object processor because theyre bullet sprites instead of player sprites, and blitting a million bullets with the object processor would be a waste of DMA time. On the Amiga you could combine bitmaps A, B, and C into D using C as a mask but the Jag blitter only has two channels.

 

edit: The DCOMPEN flag seems to be what I was looking for. Man, the technical manual sucks.

Edited by Luigi301
  • Like 1

Share this post


Link to post
Share on other sites

edit: The DCOMPEN flag seems to be what I was looking for. Man, the technical manual sucks.

Yep and yep

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...