Jump to content
IGNORED

F18A programming, info, and resources


matthew180

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?

Link to comment
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

Link to comment
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 10
Link to comment
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.

Link to comment
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
Link to comment
Share on other sites

  • 4 weeks later...

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

Link to comment
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.

Link to comment
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
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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