Jump to content
IGNORED

F18A and XB


Opry99er

Recommended Posts

After I get the XB ROMs disassembled and done this is possible.

 

Just load he F18 version of ROMs.

 

But it would help if some Assembly programmers would you know pitch in on this.

Edited by RXB
Link to comment
Share on other sites

The main problem is XB's use of the VDP memory and table locations. You can't have more colors without using more VRAM, i.e. additional pattern tables, or a larger color table (256 bytes instead of the original 32 bytes), etc. Rasmus provided a way to get access to the F18A registers from XB (see the link he provided above), but I don't know enough about XB to know if you can rearrange some of the VDP tables to reserve the extra room?

 

Some things are safe, like scrolling, changing the palette, 32-sprites on a line, etc. because they do not require VRAM use. But getting more colors for tiles and sprites requires more pattern memory. Hmm... I just had a thought. Since V1.6 or so (I'll have to look) the F18A has the ability to limit the number of tiles and move the pattern tables closer together. This would allow you to have, for example, two pattern tables (i.e. 4-colors per pixel) of 128 tiles, using the same VRAM as the original pattern table. XB would not know this is happening and it should not cause any problems. I'll have to review those changes and see what kind of flexibility we have.

Link to comment
Share on other sites

So I looked, and you can change the tile pattern generator "stride" (offset) as of F18A V1.6. So, how to explain this quickly and easily...

Basically, to get more colors per pixel you need more bits to select a color. On the original 9918A family, the pattern chooses if the pixel is a foreground or background color, and the color table defines what color is actually displayed. So with one pixel you get two colors, and in a single byte you can define eight adjacent pixels. This should be completely familiar to everyone here.

For the F18A to add more color capability, I needed to add more bits per pixel. There are basically two ways to do this:

1. Use more bits in a byte to select colors. For example, using two bits in each byte allows for up to four colors (00, 01, 10, 11) per pixel, but now you can only define four pixels in a single byte. This also has a side effect that it makes all existing pattern definitions incompatible with this kind of color selection.

2. Bit planes. This is where you take the same bit position from multiple bytes, then combine them to make the color selection. This is the method used on the NES (which uses a modified 9918A core) and some other systems, so I used this method in the F18A. Doing this means all existing pattern definitions remain compatible and that newer multi-color patterns only need to add additional bit-planes to define extra colors.

Defining patterns for bit-plane tiles can be somewhat of a pain in the ass, but thankfully Magellan supports the F18A muli-color tile definitions!

Now you have to store the extra bytes that make up the bit-planes for the extra colors. Since the original Tile and Sprite Pattern Generator Tables (PGT) are 2K in size (256 tiles * 8-bytes per tile = 2048 bytes), when you enable the extra colors (via Enhanced Color Mode (ECM) 2 and 3), the extra pattern data is pulled from VRAM immediately following the original PGT. Essentially the PGT in ECM2 is 4K, and in ECM3 it is 6K.

For example, say you ware talking about ECM2 (2-bits per color):

Bytes in PGT:
   0 .. 2047 - MSbit of pattern color index
2048 .. 4095 - LSbit of pattern color index

First pixel row for tile 0 in ECM2 requires 2-bytes:
-------------------------
|1 |0 |1 |0 |1 |1 |0 |1 | bits from byte 0
|0 |1 |1 |1 |0 |0 |0 |1 | bits from byte 2048
|--|--|--|--|--|--|--|--|
|10|01|11|01|10|10|00|11| bits form to make color index
| 2| 1| 3| 1| 2| 2| 0| 3| decimal color index for pixel

Because of the extra memory needed for the the additional bit-planes, this can cause problems for XB since it uses VRAM for program and variable storage. To try and help better utilize VRAM when using ECM2 and ECM3, in V1.6 I added the ability to define how far apart in VRAM the bit-plane tables are. By making the offset between the bit-planes smaller, you reduce the VRAM requirements with the trade-off that you have fewer unique tiles available.

To implement this there are two bits in VR29 to define the offset size for both Tile and Sprite PGTs:

-- Usable      Memory Used
-- Tiles    ECM0/1  ECM2  ECM3
-- ---------------------------
-- 0-31     256     512   768
-- 0-63     512     1K    1536
-- 0-127    1K      2K    3K
-- 0-255    2K      4K    6K
--
-- 11 = +256, 10 = +512, 01 = +1K, 00 = +2K (default)

VR29:
      7      6            5              4          3      2          1              0      Bit number (TI numbering)
    >80    >40          >20            >10        >08    >04        >02            >01      Bit value
+----------------+--------------+--------------+--------------+--------------+--------------+
| Sprite Pattern | Tile Layer 2 | Tile Layer 2 | Tile Pattern | Tile Layer 1 | Tile Layer 1 |
| Generator      | Horziontal   | Vertical     | Generator    | Horizontal   | Vertical     |
| Offset Size    | Page Size    | Page Size    | Offset Size  | Page Size    | Page Size    |
+----------------+--------------+--------------+--------------+--------------+--------------+
  00 = 2048        0 = 1 page     0 = 1 page     00 = 2048      0 = 1 page     0 = 1 page
  01 = 1024        1 = 2 pages    1 = 2 pages    01 = 1024      1 = 2 pages    1 = 2 pages
  10 =  512                                      10 =  512
  11 =  256                                      11 =  256

So, by setting VR29 to >04 (1024 bytes between bit-plane bytes) and enabling ECM2 (VR49 to >30), you get 2-bits per pixel color for 128 tiles in the same 2K as the original PGT. The only other concern is that in all the ECMs, the enhanced color attribute table is automatically enabled (this gives you per-tile attributes like x/y flip, priority over sprites, transparency, individual palette select), so the color tables goes from 32 bytes to 256 bytes. Although in this case only the first 128 entries in the color table would be required. I'm not sure about XB's use / placement of the color table, but if it could be put somewhere that has the extra room, then this would be totally possible and transparent to XB.

 

Link to comment
Share on other sites

The main problem is XB's use of the VDP memory and table locations. You can't have more colors without using more VRAM, i.e. additional pattern tables, or a larger color table (256 bytes instead of the original 32 bytes), etc. Rasmus provided a way to get access to the F18A registers from XB (see the link he provided above), but I don't know enough about XB to know if you can rearrange some of the VDP tables to reserve the extra room?

 

Some things are safe, like scrolling, changing the palette, 32-sprites on a line, etc. because they do not require VRAM use. But getting more colors for tiles and sprites requires more pattern memory. Hmm... I just had a thought. Since V1.6 or so (I'll have to look) the F18A has the ability to limit the number of tiles and move the pattern tables closer together. This would allow you to have, for example, two pattern tables (i.e. 4-colors per pixel) of 128 tiles, using the same VRAM as the original pattern table. XB would not know this is happening and it should not cause any problems. I'll have to review those changes and see what kind of flexibility we have.

Yea a plain console this would be tough at best and you could imbed the Assembly routines into XB GPL then move and executed them from Scratchpad in a Console.

 

How much space is needed to do this?

 

Actually you could do this for most modules provided the space needed is to to much.

 

VDP memory for XB we have:

 

>0000 - >02FF Screen image table

>0300 - >036F Sprite Attribute table

>0370 - >03EF XB pointers and flags and VDP Rollout buffer

>03F0 - >077F Pattern Character Table

>0780 - >07FF Sprite Motion Table

>0800 - >081F Color Table

>0820 - >08BE Crunch Buffer (XB program lines are converted to tokens here)

>08C0 - >0957 Edit Buffer (lines typed are saved here as you typed them and not tokenized)

>0958 - >0967 Value Stack (used by everything from XB ROM to Floating Point and subroutine GPL)

>0968 - >37D7 XB Stirngs, Dynamic Symbol Tables, Static Symbol Table, PABs.(Numeric values, Line Number Table, Program Space)

 

As you can see bleed over moving stuff is a issue and major care must be taken to change this, unless you do like I want to do and just rewrite XB ROMs and GPL.

You could currently move some tables but you give up program and string space in return. (TML comes to mind)

Edited by RXB
  • Like 1
Link to comment
Share on other sites

Post #9 in the thread "80 columns with F18A and Extended BASIC" has the source code for the 80 column routines. It shows how to reserve additional space in the VDP RAM. Adapt that to your needs and you can do just what you are talking about.

So as it is interrupt driven it can not allow other interrupts like a mouse driver. But 1920 bytes is not bad though.

This could easily be included in XB with a XB call like CALL F18 that does both a CALL INIT and loads the routine.

Link to comment
Share on other sites

So how about simply setting dip switch functions through XB?

 

Even something simple like a CALL INIT to toggle the emulated scanlines on and off?

 

It would be nice if we lowly basic programmers could have even minimal access to the F18A feature set.

  • Like 2
Link to comment
Share on other sites

So as it is interrupt driven it can not allow other interrupts like a mouse driver. But 1920 bytes is not bad though.

This could easily be included in XB with a XB call like CALL F18 that does both a CALL INIT and loads the routine.

Actually, it's not hard to run more than one interrupt routine. Lets say a routine for a mouse driver is running. The address of that routine will be at >83C4. Just before plugging the address of your routine into >83C4, copy the address there into some memory location. Then load the address of your routine to >83C4 which will turn it on. When your routine is finished, before returning take a look to see what used to be at >83C4. If it was >0000 then just return; otherwise branch to that address which is the address of the interrupt routine that was running when you loaded yours.

 

When the 80 column routines start up, the top of the stack is modified to reserve additional VDP ram. But the XB roms didn't get the message and when a garbage collection happens they reset the top of the stack to v0968. The interrupt routine looks to see if there has been a garbage collection. If so, then it resets the pointers to the top of the stack to be where I want them. If you tweaked RXB a bit you could handle this automatically. Find a place in vdp ram to hold the desired address for the top of the stack. Default would be >0968. Then something like CALL STACK(2000) would put >2000 there so that garbage collection would know to set the top of the stack to >2000. Then just a little adjustment to the garbage collection routine and you could reserve as much or as little vdp ram as you want. I don't think you'd want to do this within a running program.

  • Like 3
Link to comment
Share on other sites

So how about simply setting dip switch functions through XB?

 

Even something simple like a CALL INIT to toggle the emulated scanlines on and off?

 

It would be nice if we lowly basic programmers could have even minimal access to the F18A feature set.

 

Rasmus did just that. See the link he included in post #3 above. There are functions to write to the VDP registers, which lets you access any of the F18A's enhanced features.

  • Like 1
Link to comment
Share on other sites

Actually, it's not hard to run more than one interrupt routine. Lets say a routine for a mouse driver is running. The address of that routine will be at >83C4. Just before plugging the address of your routine into >83C4, copy the address there into some memory location. Then load the address of your routine to >83C4 which will turn it on. When your routine is finished, before returning take a look to see what used to be at >83C4. If it was >0000 then just return; otherwise branch to that address which is the address of the interrupt routine that was running when you loaded yours.

 

When the 80 column routines start up, the top of the stack is modified to reserve additional VDP ram. But the XB roms didn't get the message and when a garbage collection happens they reset the top of the stack to v0968. The interrupt routine looks to see if there has been a garbage collection. If so, then it resets the pointers to the top of the stack to be where I want them. If you tweaked RXB a bit you could handle this automatically. Find a place in vdp ram to hold the desired address for the top of the stack. Default would be >0968. Then something like CALL STACK(2000) would put >2000 there so that garbage collection would know to set the top of the stack to >2000. Then just a little adjustment to the garbage collection routine and you could reserve as much or as little vdp ram as you want. I don't think you'd want to do this within a running program.

You know we will need a different version for SAMS RXB that works with the F18 as there will not be any VDP Stack which will all be in SAMS RAM instead.

 

And there is a place already designed to hold top of stack: >83BD is top of VDP stack and >83AF is VDP Stack base.

Also there are like 4 other pointers that save copies Top of VDP Stack and VDP Stack base.

 

More than one stack DATA STACK and VALUE STACK.

 

TOPSTK EQU >8310 Top of data stack pointer

STVSPT EQU >8324 Value-stack base

LSUBP EQU >8348 Last subprogram block on stack

VSPTR EQU >836E Value stack pointer

RSTK EQU >8388 Subroutine stack base

STKMIN EQU >83AF Base of data stack
STKMAX EQU >83BD Top of data stack
VRAMVS EQU >0958 Default base of value stack
These are all the Equates in GPL Source on Stack in XB.
I will put this on my todo list of RXB and RXB SAMS.
Edited by RXB
Link to comment
Share on other sites

I stumbled onto the MLC site and noticed that it supports the F18A. MLC is a set of extensions for XB.

 

I don't know enough about either MLC or the F18A to know how complete the support is. Perhaps the author of MLC can comment on this. He's a member on this site and started the MLC thread here:

 

http://atariage.com/forums/topic/189727-mlc-and-precompiler-updated/?p=2399547

Here are some of the You Tube videos showing what MLC can do with the F18A:





There are more videos as well as documentation at the MLC site.
  • Like 1
Link to comment
Share on other sites

The default number of sprites on a line is selectable via a jumper, as well as via software. I suspect most people have the setting to allow all 32-sprites on a line, since you get the most benefit from that. Don't worry about everyone else though, write your games for yourself and let others adjust to you. ;-)

  • Like 1
Link to comment
Share on other sites

Matthew, can you INIT the 32 SPRITEs on a line at the start of your program (or vice versa)? The question would then be, "how do you reset back to the system default?"

 

Perhaps a memory location could be read prior to initialization of the setting... then set it, then (on program exit) reset back to standard if necessary.

Edited by Opry99er
Link to comment
Share on other sites

The F18A has a reset function that you can call in a quit key handler, but if the user presses a hard reset button the code will not be called.

 

In Skyway I have the opposite issue: I'm relying on the 4 sprites per line limitation to mask off sprites when they reach the lower third of the screen. But the jumper setting that most people are using on their F18As means that this trick doesn't work. So I will have to detect the F18A and set up the #sprites-per-line register in order to make my code work as intended, which is a bit annoying (note that I haven't actually done this yet).

Link to comment
Share on other sites

Using Rasmus' functions for XB you can unlock the F18A and access the settings you need. The F18A can set the number of sprites on a line from 1 to 32 by writing the value (1..32) to VR30. If you write a 0 (zero) to VR30, if will reset the sprite max to the jumper setting (4 or 32). Thus you can unlock, set your limit to 32, then when you are done you can reset to the user's default.

 

You can also unlock the F18A, change some of the enhanced settings, then relock the F18A if you don't want it to remain unlocked. You might do this because certain things are enabled when you unlock the F18A that might cause undesirable side effects in the XB environment. Probably not necessary, but it is possible if you need it.

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