Jump to content
matthew180

F18A programming, info, and resources

Recommended Posts

I have tried both but the former is far more interesting. This is really funny: Try to run E/A#3 SLSSIN from the attached disk, then run a game (I can recommend Donkey Kong).

 

So clearly this works without involvement from the host program. I assume you're not just letting the GPU run at full speed but you're using VR50 to trigger the code at every scanline?

 

So what's the overall framework for something like that then? I'd imagine something like this:

  • Load VR54 and VR55 with the start address of your GPU code
  • End your GPU code with an IDLE statement
  • Let the host program set VR50 to trigger the GPU code every scanline (As in, set VR50 to a value ORed with 64).

But where does execution take off when the next scanline is hit? After the IDLE statement, or at the original location set in VR54/55?

 

Does the above sound about right?

Share this post


Link to post
Share on other sites

 

So clearly this works without involvement from the host program. I assume you're not just letting the GPU run at full speed but you're using VR50 to trigger the code at every scanline?

 

So what's the overall framework for something like that then? I'd imagine something like this:

  • Load VR54 and VR55 with the start address of your GPU code
  • End your GPU code with an IDLE statement
  • Let the host program set VR50 to trigger the GPU code every scanline (As in, set VR50 to a value ORed with 64).

But where does execution take off when the next scanline is hit? After the IDLE statement, or at the original location set in VR54/55?

 

Does the above sound about right?

 

Yep. My demo uses a skeleton like this:

CPU:
----
*      Init GPU routine
       [Copy GPU code to VDP RAM]
*      Set the GPU PC which also triggers it
       LI   R0,GPUPRG/256+>3600
       BL   @VWTR
       LI   R0,>3700
       BL   @VWTR
LOOP   JMP LOOP

GPU:
----
GPUPRG LI R15,>47FE            * Set up stack pointer
       [Other init code here]
*      Set the HSYNC trigger
       MOVB @B40H,@>6032       * Set reg >32 from GPU side
RETURN IDLE
       [HSYNC code here]
       JMP RETURN

ScanLineScroll.a99

Share this post


Link to post
Share on other sites

Yup, that did the trick. I'd neglected to put a jump back to the first statement of the loop, so the GPU resumed in lalaland once triggered a second time.

 

So, I am building a level editor for Alex Kidd's F18A port and figured I'd put together a demo of some F18A features myself. This one focuses on parallax scrolling. It uses the two tile layers, but also the "trigger on next scanline" feature of the GPU to create a fake 3rd layer (the house in the background) and an extra parallax effect on the floor.

 

Video for those without F18A:

 

C-code running on the GPU is extremely simple:

// Define VRAM memory locations we want to read/write
#define VREG25		*((volatile unsigned char*)0x6019)
#define VREG27		*((volatile unsigned char*)0x601b)
#define VREG50		*((volatile unsigned char*)0x6032)
#define SCANLINE	*((volatile unsigned char*)0x7000)
#define SCROLL1		*((volatile unsigned char*)0x1801)
#define SCROLL2		*((volatile unsigned char*)0x1802)

int main(int argc, char *argv[])
{
	// Set stack pointer, not needed here but...
	__asm__("LI r15,>47fe");

	unsigned char 	scroll1 = 0, scroll2 = 0;
	int 			factor = 0;

	// Write flag to trigger GPU every scanline to video register 50 (0x32)
	VREG50 |= 0x40;

	// loop that runs once every scanline
	while (1)
	{
		__asm__("IDLE");

		// Check for start of image
		if (SCANLINE == 0)
		{
			scroll1 = SCROLL1;
			scroll2 = SCROLL2;

			// Only scroll half the amount for the top half of the background layer
			VREG27 = scroll2 >> 1;
			VREG25 = scroll1;
		}

		// Bottom half of background layer scrolls at normal speed
		if (SCANLINE > 96)
		{
			VREG27 = scroll2;
		}

		// Create extra paralax effect on floor
		if ((SCANLINE > 152) && (SCANLINE < 184))
		{
			factor = SCANLINE - 152;
			factor = factor * (80 - SCROLL1);
			scroll1 = SCROLL1 - (factor >> 7);
			VREG25 = scroll1;
		}
	}	

	return 0;
}

And a disk image for those that want to run it on the real thing is attached as well.

f18atest.dsk

  • Like 9

Share this post


Link to post
Share on other sites

It's a cool demo, bit it does not close graphics mode properly on R.I.

 

Indeed it doesn't, but it also doesn't run the ISR so I'm curious how you get out of the program without power cycling?

Share this post


Link to post
Share on other sites

 

Indeed it doesn't, but it also doesn't run the ISR so I'm curious how you get out of the program without power cycling?

 

Reset switch.

Share this post


Link to post
Share on other sites

 

Indeed it doesn't, but it also doesn't run the ISR so I'm curious how you get out of the program without power cycling?

 

 

Reset switch.

 

Yep, Tursi's little PS/2 keyboard adapter is awesome... "ALT + F12"... it works great with Gazoo's BOOT update as well.

Share this post


Link to post
Share on other sites

Makes sense, but how would a program be able to restore GM1, color palette, etc... in such a scenario? It can never catch the reset, right?

Share this post


Link to post
Share on other sites

No you can't, so people shouldn't use a reset switch with F18A programs. On the other hand, the programs should include a soft reset handler that resets the F18A and restores the palette.

Share this post


Link to post
Share on other sites

Yup, I know... but hey, this doesn't count as a real program, now does it? ;).

Anyway, I'll take that into account next time.

Share this post


Link to post
Share on other sites

Not on the actual system, but I'm figuring out what sprites would look like for this. I edited sprites from the Gameboy, Master System and Genesis from the original game to match the F18A's requirements:

post-33891-0-51770300-1434655949_thumb.png

 

Only the Genesis version fits with the background, imho, but that is really at the edge of what we'd be able to do. Each player character would be made up of 15-16 16x16 sprites, which immediately puts us at the limit of what we have. We do have enough room for the two sprite's patterns in VRAM though, but we'd have to stream in the animations from the host system.

Share this post


Link to post
Share on other sites

Matthew, If I set the pattern table to start at 0x3000 in ECM3 mode, is there a way to make the F18A read the third bitplane from the GPU RAM portion above 0x3FFF?

Share this post


Link to post
Share on other sites

Unfortunately not. The video circuits are restricted to the original 16K of VRAM. You can change the stride of the color bytes though, which means you lose characters but also reduce the amount of memory required in the enhanced color modes.

Share this post


Link to post
Share on other sites

I figured as much. I'm already counting on the ability to reduce the stride between bitplanes to make the sprite pattern table fit in 3k instead of the normal 6k. 64 patterns per player are enough to display the on-screen sprites, but I also need to find room to put a backbuffer somewhere in memory for the next animation frame while it's being uploaded from the host system. Unless there's a way to optimize VRAM usage that I haven't figured out yet, I think a streetfighter game would need to be restricted to one plane only.

  • Like 1

Share this post


Link to post
Share on other sites

Is the RNG at >9000 still available from GPU programs? If so, is it implemented in js99er?

*edit* Nevermind... just re-read the changelog, it's clearly there that it is removed.

Edited by TheMole

Share this post


Link to post
Share on other sites

Sorry for spamming the thread with all my questions, but is the 16-color fat pixel BML mode documented somewhere? My assumption is that the destination operand's lower nibble will define the color of a fat pixel, and that e.g. the following command would plot a pixel with color 14 at location (32,32) in the BML:

LI    r0,>2020
LI    r1,>000e
PIX   r0,r1

That's not what I'm seeing however, but I might be doing something wrong...

Share this post


Link to post
Share on other sites

Sorry for spamming the thread with all my questions, but is the 16-color fat pixel BML mode documented somewhere? My assumption is that the destination operand's lower nibble will define the color of a fat pixel, and that e.g. the following command would plot a pixel with color 14 at location (32,32) in the BML:

LI    r0,>2020
LI    r1,>000e
PIX   r0,r1

That's not what I'm seeing however, but I might be doing something wrong...

 

I don't think the fat pixel BML works with PIX, you have to write directly to VDP memory.

Share this post


Link to post
Share on other sites

 

I don't think the fat pixel BML works with PIX, you have to write directly to VDP memory.

 

Ok, cool, thanks.

 

Well, inspired by sometimes99er's fire demo, I did one for the f18a. The cool thing about the f18a is that it makes all those old DOS effects new again, so I dug out an old fire demo I did and ported it to the F18A. The result is attached, and here's a video for the f18a impaired (or lazy people):

 

https://www.youtube.com/watch?v=k2Qg-QqnJVM

 

This isn't optimized, and there is some "black snow" because I'm not double buffering, but I think it looks nice enough... Not tested on real iron yet, and NOT reset button safe :P

fire-src.tar.gz

fire.dsk

  • Like 9

Share this post


Link to post
Share on other sites

Hmmm, dunno what I'm doing wrong. In Classic99 I get nothing and on RI with an F18A I get some bars that's about it.

 

 

 

Classic99 has very limited F18A support. Did you install firmware version 1.6 on your RI?

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...