Jump to content
IGNORED

F18A programming, info, and resources


matthew180

Recommended Posts

8 hours ago, matthew180 said:

Not currently, no.  Sorry.  Although I think this could be added in the next firmware update.  The BML is only addressed during TL1 processing, so the BML's priority bit is between TL1 and the BML

(5 years ago, yikes) I tried  a BML to mask out the bottom 3-4 rows of the screen.

 

TL1 and TL2  were scrolling (different speeds) for a parallax effect. I wanted a fixed status display at the bottom.  (The old "scrolling window" feature was gone.) 

 

BML would cover ties 21-24. Row 21 would be solid BML  to hide partial tiles. Tiles to be erased after scrolling 8 pixels. I would draw status into BML for rows   22-24.

With a 256x32 bitmap, 2 bits per pixel, I got a very confusing result. (Hardware F18A, recent firmware.) Probably my error, but to clarify--

 

 

Is there a way for the BML to mask both TL1 and TL2?

 

Sprites aren't an issue. 

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, FarmerPotato said:

Row 21 would be solid BML  to hide partial tiles.

 

If you were doing parallax scrolling, that would be left-to-right, so I'm confused what masking you needed at the bottom?  Just put empty tiles on TL1 and TL2 for those rows.  If you are using the expanded name-tables, then you do not need any left or right edge masking (which TL2 was designed to do in cases where is was needed).

 

1 hour ago, FarmerPotato said:

Is there a way for the BML to mask both TL1 and TL2?

 

Not currently.  The BML and TL1 can swap which is on top, but TL2 will always be in front of both.

 

You could use TL1 and the BML for the scrolling, and leave TL2 for things like the score and fixed-place text, etc..  The BML is like a big sprite and can be moved around.  However, I would also think that some of the techniques Rasmus has come up with (like the driving games) could be used to crate a parallax effect much easier and more efficiently.

 

Alternatively you can use a single tile layer and use the GPU to set the horizontal scroll for every pixel row.  Every 8 rows it could also shift the horizontal tiles in a row so you do not need the expanded name tables.

 

I'm working on a firmware update, and a possible new feature is support for horizontal and vertical scrolling without needing the extra name tables.  I think I'm calling it "border scroll mode", but I might change it to "window scroll mode" (although I don't like "modes" so I should probably pick a new word for that too).  Basically the name tables becomes 34x26 (or 34x32 if ROW30 is enabled), but the displayed tiles will be the center 32x24.  This leaves a border of tiles all the way around the tile layer that is used to provide the edge data when scrolling takes place.

 

This does mean after scrolling 8 pixels in any direction you will have to reset the scroll and tile-shift the whole name table, but you eventually have to do this anyway.  With this technique the name table only needs to grow by 116 bytes, i.e. 768 to 884 (1088 in ROW30), which is way less memory than doubling or quadrupling the name table space for each layer.

Link to comment
Share on other sites

2 hours ago, matthew180 said:

 

2 hours ago, matthew180 said:

If you were doing parallax scrolling, that would be left-to-right, so I'm confused what masking you needed at the bottom? 

Oh, it's both horizontal and vertical travel. Horizon isn't fixed. 
 


 

 

2 hours ago, matthew180 said:

Basically the name tables becomes 34x26 (or 34x32 if ROW30 is enabled), but the displayed tiles will be the center 32x24.

Would it have to be a contiguous row? Address calculation gets messier--

MOV R3,R0  Row

SLA R0,5  MPY by 32

A R3,R0

A R3,R0

 

But I guess you would be refreshing the whole table in one go, so VDPWA is set once. 

For scrolling, I made TL2 into four screens, so the refresh portion is always off-screen. TL1 scrolls half the speed so I allocated just 64x30 & refresh off screen. 

Link to comment
Share on other sites

3 hours ago, matthew180 said:

This does mean after scrolling 8 pixels in any direction you will have to reset the scroll and tile-shift the whole name table, but you eventually have to do this anyway.  With this technique the name table only needs to grow by 116 bytes, i.e. 768 to 884 (1088 in ROW30), which is way less memory than doubling or quadrupling the name table space for each layer.

Would it be possible to allow the scroll to wrap at the edges?  On the right side: 33 to 0, and at the bottom: 25 to 0 (or 31 to 0 w/ ROW30).

 

I also can think of a situation where I would want BM layer on top of both TL1 and TL2.

Link to comment
Share on other sites

1 minute ago, PeteE said:

Would it be possible to allow the scroll to wrap at the edges?

 

That is the native functionality if you just start changing the scroll registers without any masking (from TL2, etc.) or setting up the additional name tables.

 

Here is a screenshot of some early testing of the BML and scrolling.  This is the stock Mater Title Screen, with a GPU program running that is updating registers (like the BML control), and the horizontal scroll register being updated at certain locations.  The "READY-PRESS ANY KEY TO BEGIN" text looks blurry because it is horizontal scrolling, along with the color bars in places, etc..  The console has no idea this stuff is happening, and there is no 9900 code involved.

 

image.thumb.png.1cc7dc66531990850100a9c525710840.png

 

 

11 minutes ago, PeteE said:

I also can think of a situation where I would want BM layer on top of both TL1 and TL2.

 

I can probably make that happen.

Link to comment
Share on other sites

7 minutes ago, matthew180 said:

That is the native functionality if you just start changing the scroll registers without any masking (from TL2, etc.) or setting up the additional name tables.

I meant with future 34x26 border scroll functionality.  I would rather have the scroll wrap instead of needing to rewrite the whole name table every 8 pixels scroll.

Edited by PeteE
Link to comment
Share on other sites

44 minutes ago, PeteE said:

I meant with future 34x26 border scroll functionality.  I would rather have the scroll wrap instead of needing to rewrite the whole name table every 8 pixels scroll.

How difficult would it be to use the GPU as a blitter to do that?

Link to comment
Share on other sites

The GPU is more than fast enough to set multiple registers between scanlines, if you have a complicated scrolling situation that requires a fixed window, just use the GPU to set up the window mid-screen. The whole value of the GPU is to easily set up exactly the situation that you need without all of them needing to be specific features. ;)

 

Link to comment
Share on other sites

4 minutes ago, OLD CS1 said:

How difficult would it be to use the GPU as a blitter to do that?

That depends on how much GPU RAM is left over after both TL1 and TL2 name and attribute tables, ECM3 patterns and ECM3 sprites.  The level data needs to be stored somewhere.

Edit: oh... blitter as a block transfer, to move the data in the name+attr tables up/down/left right.  Yeah, that would work. Good idea!

Edited by PeteE
Link to comment
Share on other sites

17 hours ago, PeteE said:

Edit: oh... blitter as a block transfer, to move the data in the name+attr tables up/down/left right.  Yeah, that would work. Good idea!

 

When I finished the base 9918A functionality in the F18A, I had a lot of room left in the FPGA.  I always intended to have a DMA for exactly this, but defining all the DMA features eventually morphed into "Why not just have a CPU?"  And if you have a CPU in the VDP, why not have it be a 9900?  Thus the GPU.

 

There is, actually, also a DMA in the F18A.  I should probably put the GPU's memory map in the register use spreadsheet.  It is documented in this thread somewhere too.

 

   -- DMA
   -- 8xx0 - MSB src
   -- 8xx1 - LSB src
   -- 8xx2 - MSB dst
   -- 8xx3 - LSB dst
   -- 8xx4 - width
   -- 8xx5 - height
   -- 8xx6 - stride
   -- 8xx7 - 0..5 | !INC/DEC | !COPY/FILL
   -- 8xx8 - trigger
   --
   -- src, dst, width, height, stride are copied to dedicated counters when
   -- the DMA is triggered, thus the original values remain unchanged.

 

This will access VRAM at 10ns per byte, per read and write (but this will probably change a little in the future firmware, and will be slightly variable between 10ns to 30ns per byte).  So copying a byte will be 10ns read and 10ns write.  So, in 1us 50 bytes can be copied.  Clearing the screen can be done in about 16us.  Moving a 2K table takes about 40us.

 

There is also the PIX instruction (replaces the XOP instruction) that is designed to read/write/update BML pixels, and can also calculate the GM2 byte to update from a pixel X,Y location.  This instruction should be documented in this thread, I hope, and I think there are some examples (I can dig some up as well).

 

         -- PIX XY,CMD
         -- Can only operate on 16K VRAM addresses.
         -- Can be written like this: XOP src,dst
         -- Uses XOP addressing modes for src (XY) and dst (CMD)
         -- SRC: XY is the pixel x,y location in 8:8 format.  Uses all source
         --      addressing modes.
         -- DST: MAxxRWCE xxOOxxPP
         -- M  - 1 = calculate the effective address for GM2 instead of the new bitmap layer,
         --          placing the VRAM address in the dst.
         --      0 = use the remainder of the bits for the new bitmap layer pixels
         -- A  - 1 = retrieve the pixel's BML effective address instead of setting a pixel,
         --          placing the VRAM address in the dst.
         --      0 = read or set a pixel according to the other bits
         -- R  - 1 = read current pixel into PP, only after possibly writing PP
         --      0 = do not read current pixel into PP
         -- W  - 1 = do not write PP
         --      0 = write PP to current pixel
         -- C  - 1 = compare OO with PP according to E, and write PP only if true
         --      0 = always write
         -- E  - 1 = only write PP if current pixel is equal to OO
         --      0 = only write PP if current pixel is not equal to OO
         -- OO   pixel to compare to existing pixel
         -- PP   new pixel to write, and previous pixel when reading

 

 

 

  • Like 3
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...