Jump to content
IGNORED

F18A programming, info, and resources


matthew180

Recommended Posts

Yeah, it's not going to run on Classic99, that's normal. But indeed, I just tested on my real hardware and it crashes there as well. The strange thing is that it runs fine in js99er.net and it is damn hard to debug on RI :?

 

*edit* The version attached to this post does run on the real deal (and it runs quite a bit faster, making the effect more convincing). I only inlined some functions in the GPU program, which probably means that my tools to compile C code for the GPU don't always work when using regular function calls. (I left the original up as well, if Rasmus wants to verify why js99er gave different results to the real HW)

 

Video proof:

https://www.youtube.com/watch?v=RY_8i_ouXc8

 

fire.dsk

Edited by TheMole
  • Like 6
Link to comment
Share on other sites

 

The version attached to this post does run on the real deal...

 

Damn, that's awesome! :thumbsup: :thumbsup: :thumbsup: :thumbsup: :thumbsup:

 

I'm curious, would it be possible to take a photo of a brick fireplace, convert it into TI format with Tursi's program and integrate your program to display with the static photo? That would probably be the best screen saver ever made for the TI.

 

I'd love to collect a whole series of screen savers for the TI, each one different showing off the power of the F18A.

  • Like 1
Link to comment
Share on other sites

Where in the original source can I see the assembly code for the GPU routines?

 

You can't, it's all C code that gets compiled by GCC. The GPU routines are in gpucode.c, get compiled to binary format (to gpucode.o, which gets transformed to gpucode.bin) and then turned into a header file via bin2h to end up as an array of bytes in gpucode.h. This header gets included in main.c and uploaded to VRAM (starting at memory locations 0x1900) by the host program.

 

If you want to see the assembled code, the simplest thing you can do is use js99er's debugger to look at VRAM from 0x1900 and onwards (roughly 300 bytes, I think). As I said, both versions upload the code to 0x1900 in VRAM, but in the broken version the entrypoint of the 'main' function is at 0x1948 (so GPU execution starts there instead of at 0x1900), with the first 0x48 bytes occupied by code that gets jumped to later (functions in C). The working version just starts at 0x1900, since there the functions are inlined.

  • Like 1
Link to comment
Share on other sites

 

Damn, that's awesome! :thumbsup: :thumbsup: :thumbsup: :thumbsup: :thumbsup:

 

I'm curious, would it be possible to take a photo of a brick fireplace, convert it into TI format with Tursi's program and integrate your program to display with the static photo? That would probably be the best screen saver ever made for the TI.

 

I'd love to collect a whole series of screen savers for the TI, each one different showing off the power of the F18A.

 

Thanks :). It should be possible to put some graphics around the fire, but not something that was output by Tursi's convert9918a (the fire effect runs completely in VRAM, and requires almost 10k of memory; a bitmap image requires 12k, so you can't have both at the same time in the F18A's 18k). Something photorealistic is probably out of the question, but character mode graphics should be doable though, perhaps even in ECM3 mode... if you want to design something in Magellan, I'd be happy to include it for you.

  • Like 1
Link to comment
Share on other sites

Yes, the two RNGs were removed to make room for more desirable features. I can provide a C function that performs the same algorithm if you want? As for the PIX instruction, it won't work with the new fat-pixel enhancement (as you discovered.) PIX is too hard wired for the BML pixel format and would have required too much ripping up to add the fat-pixel support. However, you should be able to write one fat-pixel using two PIX instructions, incrementing the X coordinate between each instruction. That might be faster than a read-mask-write for each nibble of the fat-pixel feature.

 

Very nice fire effect!

  • Like 1
Link to comment
Share on other sites

 

... if you want to design something in Magellan, I'd be happy to include it for you.

 

Thanks for the offer, but I've never played with Magellan, and don't currently have time to learn it because between work, family, and other obligations, most of my spare time has been going to Atari Age, and other computer related pursuits. :(

Link to comment
Share on other sites

Yes, the two RNGs were removed to make room for more desirable features. I can provide a C function that performs the same algorithm if you want? As for the PIX instruction, it won't work with the new fat-pixel enhancement (as you discovered.) PIX is too hard wired for the BML pixel format and would have required too much ripping up to add the fat-pixel support. However, you should be able to write one fat-pixel using two PIX instructions, incrementing the X coordinate between each instruction. That might be faster than a read-mask-write for each nibble of the fat-pixel feature.

 

Very nice fire effect!

 

No worries, I just plugged in a C function that I'd used somewhere else before. Is it correct that the timers you added in favor of the RNG are not available to the GPU?

Link to comment
Share on other sites

Correct, the new timer is not accessible by the GPU. It bothered me a lot, but I'm at 98% utilization of the FPGA and the timer is a wide data access and just would not fit.

 

However, the GPU can go idle and then be interrupted by the HSYNC and/or VSYNC, poll the current horizontal line, etc. Depending on what you are doing these may be sufficient?

 

For example, the VSYNC interrupt is useful to do something every frame:

 

    LI   R1,>0200
    SOCB R1,@>6032     // Set bit >02 in VR50 (VSYNC Trigger)

vsync_loop:
    .
    . do stuff during current active frame.
    .

    // wait for VSYNC
    IDLE

    .
    . VSYNC just happened, do stuff for the next frame.
    .

    JMP vsync_loop
I think you already know all that though...
  • Like 1
Link to comment
Share on other sites

 

Thanks :). It should be possible to put some graphics around the fire, but not something that was output by Tursi's convert9918a (the fire effect runs completely in VRAM, and requires almost 10k of memory; a bitmap image requires 12k, so you can't have both at the same time in the F18A's 18k). Something photorealistic is probably out of the question, but character mode graphics should be doable though, perhaps even in ECM3 mode... if you want to design something in Magellan, I'd be happy to include it for you.

 

I only got around to viewing this on the hardware today, and it looks great, but why does it take up 10k VDP RAM when it's not bigger than that? A full screen bitmap takes 12k according to my calculations.

 

Do you have any palette colors left for displaying anything around the fire?

Link to comment
Share on other sites

 

I only got around to viewing this on the hardware today, and it looks great, but why does it take up 10k VDP RAM when it's not bigger than that? A full screen bitmap takes 12k according to my calculations.

 

Do you have any palette colors left for displaying anything around the fire?

 

You're right, I miscalculated, It needs roughly 5k. The BML is initialized at 80x80 pixels, but I should've used 40x80 for my calculations since I'm using fat pixels. So, the effect requires an offscreen buffer of 40x80 bytes (not nibbles), so 3200 bytes. And the BML layer itself needs half of that (nibbles instead of bytes), so another 1600 bytes adding up to 4800 bytes. The program itself is around 300 bytes, so we need 5100 bytes in total for the fire effect and not 9900 like I originally calculated using an 80x80 buffer.

 

So yes, it should be possible to fit in a bitmap image.

Plenty of colors still available, since I'm only using one of 4 available 16-color palettes. Just need to assign a different palette to the BML.

 

Do you have the original for the picture somewhere?

Link to comment
Share on other sites

The same image in ordinary bitmap mode but with a custom F18A palette made using Tursi's converter. I can't really say what I like best, but the fat pixel mode leaves more freedom to the programmer.

 

attachicon.giffireplace2.png

 

Like you, I find it too close to tell, at least with the examples being so small. I'm looking forward to a finished product on this one. It's beautiful and would give us all an excuse to leave the TI on more often. The ultimate addition (if any active memory is left) would be to add a few very short and small audio clips of fireplace sounds. I figure 3-5 randomly selected, so it never sound the same would be interesting.

Link to comment
Share on other sites

  • 4 weeks later...

Matthew (or Rasmus or anyone else who's programmed the F18A's scroll registers),

 

I'm trying to figure out how to do scrolling with pages on the F18A. I'm looking at both the documentation and the register sheet, but I'm getting a bit confused on how things are supposed to work in v1.6. In the pdf file, there's mention of a "start page" bit in register 29, which determines the page offset for the scroll value in registers 27 and/or 28. But in the v1.6 version of the register document these bits are gone.

 

How does one select the start page in the new firmware?

Link to comment
Share on other sites

This is my setup code:

void load_title_f18a()
{
	// Blank screen so we don't show garbage
	VDP_SET_REGISTER( 0, 0x00);
	VDP_SET_REGISTER( 1, 0x00);
	VDP_SET_REGISTER( 7, 0x00);		// Black border

	VDP_SET_REGISTER( 4, 0x05);		// Pattern table at 4 * 0x800 (0x2000 - 0x3800)

	VDP_SET_REGISTER( 2, 0x04);		// Nametable, 0x04 * 0400 (0x1000 - 0x1400)
	VDP_SET_REGISTER( 3, 0x60);		// Attribute table, 0x60 * 0x40 (0x1800 - 0x1c00)
	VDP_SET_REGISTER(10, 0x00);		// Second name table at 0 * 0x400 -> 0x0000 - 0x800
	VDP_SET_REGISTER(11, 0x20);		// Second attribute table at 32 * 64 = 0x20 * 0x40 -> 0x0800 - 0x1000

	VDP_SET_REGISTER(29, 0x10);		// Set 2 vertical pages for TL1
	VDP_SET_REGISTER(49, 0xb0);		// 0xb0 = TL2 enable | ECM3 for tiles
	VDP_SET_REGISTER(50, 0x02);		// Per position attributes

	vdpmemset(0x0000, 0x00, 0x4000);

	// Load color, pattern and sprite generator RESources from ROM
	rom_to_vram(RES_START(title_nt_f18)		, RES_END(title_nt_f18) - 768		, 0x0000);
	rom_to_vram(RES_START(title_attr_f18)		, RES_END(title_attr_f18) - 768		, 0x0800);
	rom_to_vram(RES_START(title_nt_f18) + 768	, RES_END(title_nt_f18)				, 0x1000);
	rom_to_vram(RES_START(title_attr_f18) + 768	, RES_END(title_attr_f18)			, 0x1800);
	rom_to_vram(RES_START(title_patt_f18)		, RES_END(title_patt_f18)			, 0x2800);
	rom_to_ram (RES_START(title_pall_f18)		, RES_END(title_pall_f18)			, (unsigned char*)palettes);

	// Copy palettes to CRAM
	VDP_SET_REGISTER(47, 0xC0);		// Palette write mode | Auto increment | Start at address 0
	for (int i = 0; i < 64; i++)
	{
		VDPWD = (palettes[i] & 0xff00) >> 8;
		VDPWD = (palettes[i] & 0x00ff);
	}
	VDP_SET_REGISTER(47, 0x00);		// VRAM write mode

        VDP_SET_REGISTER(26, 0x50);             // Scroll 80 pixels up, to hide title card
	VDP_SET_REGISTER( 1, 0x40 | VDP_MODE1_INT);		// GM1 / No blanking | Interupt enabled
}

The rom_to_vram calls load the data into VRAM from other banks in the cartridge, but I've verified that these work fine. A VRAM dump is attached for reference.

 

I'm trying to "drop" TL2 into view (it contains the game's title, I'm sure you know the effect I'm after...). It title scrolls out of the way nicely, but the lowest 80 pixels (with the settings above) show 'garbage', which I'm sure it's picking up from elsewhere in VRAM but I can't figure out from where.

 

Note that I'm using location based attributes, which may change things from 'normal' tile-based attributes.

 

vram_dump.txt

Link to comment
Share on other sites

Just to add: Nametable 2 is at position 0, which technically I think is a 4k boundary? Nametable 1 is at 4k, but I'm not scrolling that one. Perhaps I should try swapping them?

 

*edit* Nope, didn't help... still shows garbage in the second page. Different garbage... :), but still garbage...

Edited by TheMole
Link to comment
Share on other sites

I found something that Matthew wrote when we discussed the 1.6 firmware:

 

Single Name Table, hsize='0', vsize='0':
The NTBA selects the location of the name table on 1K boundaries. Scrolling will always wrap the single name table.

Two Name Tables, hsize='1', vsize='0':
The NTBA selects the location of the two name tables on 2K boundaries. Essentially the NTBA becomes 3-bits in size instead of 4-bits, with the LSbit (NTBA(3)) being the initial table-select or what I used to call "start-page". Vertical scrolling will wrap the pages top-to-bottom, but scrolling left-to-right will be across both name tables.

Two Name Tables, hsize='0', vsize='1':
This one is a little different because there is a 1K chunk between the tables. The NTBA selects the location of the two name tables on 4K boundaries, but only the 1st and 3rd 1K-blocks are used. Horizontal scrolling will wrap the pages left-to-right, but scrolling top-to-bottom will be across the 1st and 3rd 1K name tables. The NTBA is essentially 2-bits (0..1) and NTBA(2) is the vertical start-page select.

Two Name Tables, hsize='1', vsize='1':
Select the name table location on 4K boundaries. NTBA(0..1) select the location of the four tables, NTBA(2) selects the vertical start-page, NTBA(3) selects the horizontal start-page. Scrolling is across all four name tables.

The NTBA is limited to 4-bits simply due to compatibility. Since the color table was originally 8-bits it has finer location control. In position-attribute mode the attribute addressing is identical to getting a tile name from a name table. There are two 6-bit counters that form the bottom 12-bits of the address when combined with the NTBA(2..3) bits and hsize/vsize bits.

That leave the top-two bits of the address to come from the NTBA(0..1). However, for the position attribute, those bottom 12-bits are *added* to the the CTBA to get the full 14-bits. It looks something like this:

0 1 2 3 4 5 6 7 8 9 10 11 12 13
| NTBA(0..1) | VCNT(0) | HCNT(0) | VCNT(1..5) | HCNT(1..5) | 

0 1 2 3 4 5 6 7 8 9 10 11 12 13
| CTBA(0..7) | 0 0 0 0 0 0 |
-----------------------------------------------------------------
+ | 0 0 | VCNT(0) | HCNT(0) | VCNT(1..5) | HCNT(1..5) |

The low 12-bits make a tile address based on the raster screen location. When combined with the NTBA(0..1) bits it makes an addresses in VRAM starting from one of four offsets (>0000, >1000, >2000, >3000). When added to the CTBA it selects the same byte, just from a different base address.

The VCNT(0) and HCNT(0) bits depend on the hsize/vsize bits, so they will toggle to select the alternate page if the size is set to '1', otherwise they maintain their original value as derived from the NTBA at the start of each scan line.

Link to comment
Share on other sites

Thanks Rasmus, that helped! So basically, the 4 pages are always arranged as follows:

   PAGE1   |   PAGE2
   BASE    | BASE + 1k
-----------------------
   PAGE3   |   PAGE4
 BASE + 2k | BASE + 3k

Regardless of the configuration of the page sizes, they merely "enable" the pages.

 

Yep, and the color table/tile attribute pages, even though they can be based at any >40 boundary, will have the same offsets between them.

Link to comment
Share on other sites

Check out post #113 in this thread:

 

http://atariage.com/forums/topic/207586-f18a-programming-info-and-resources/page-5?do=findComment&comment=2848296

 

The info appears to still be valid with the v1.6 firmware. The name table setup for scrolling was loosely based on the NES design, which I figured would be somewhat familiar to some people.

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