Home Page
Posted By: Golden Child Atari 800 choplifter - 09/24/21 01:18 AM
I was trying to figure out how the atari 800 worked, so I could add a printer device to it.

As it happens, you end up getting interested in how things are put together, and want to figure out the entire system.

I remembered how much I wanted to play choplifter on the a800 driver and it always bugged me that it flickered and was unplayable.

After seeing how display lists work, it appeared that it was writing DLISTH while it was in the middle of executing a displaylist with the ANTIC.

Code
WRITE DLISTH = 2000   ':maincpu' (E7F4)
WRITE DLISTL = 2000   ':maincpu' (E7FA)
scanline = 8 new_cmd = 70   m_dpage=2000 m_doffs=1 
scanline = 10 new_cmd = 70   m_dpage=2000 m_doffs=2 
scanline = 18 new_cmd = 70   m_dpage=2000 m_doffs=3 
WRITE DLISTH = 2100   ':maincpu' (8E32)
scanline = 20 new_cmd = 10   m_dpage=2000 m_doffs=4 
scanline = 22 new_cmd = c2   m_dpage=2000 m_doffs=5 
scanline = 2a new_cmd = 4f   m_dpage=2000 m_doffs=8 
scanline = 2b new_cmd = 4f   m_dpage=2000 m_doffs=b 
so according to the manuals that I could find online, DLISTH is supposed to write the upper byte, and DLISTL is supposed to write the lower byte.

from the Altirra hardware reference manual:
Quote
Instruction pointer
The DLISTL and DLISTH registers contain the instruction pointer used to fetch the display list. At the end of each
mode line, ANTIC fetches a new instruction at the location pointed to by DLISTL/DLISTH into the instruction
register (IR), and then increments the pointer. This continues until a jump instruction is reached, which then
loads a new address into DLISTL/DLISTH. ANTIC does not store the start of the display list and has no registers
to do so; the display list must either loop or be restarted by the CPU.
The display list can reside anywhere in the 64K address space, but it cannot cross a 1K boundary. This is
because the DLISTL/DLISTH register is actually split into 6 bit and 10 bit portions, where the lower 10 bits
increment and the upper 6 bits do not.14 As a result, during normal execution the display list will wrap from the
top of a 1K block to the bottom during fetching, e.g. $07FF to $0400. This will happen even in the middle of a
three-byte LMS or jump instruction. Jump instructions are not limited and can cross 1K boundaries to any
address.
DLISTL/DLISTH are live during display list execution and any write to either will immediately change the address
used for the next display list fetch. Because of the possibility of display list interrupts, it is dangerous to do this in
the middle of a display list, as changing only one of the address bytes may cause ANTIC to execute random
memory as a display list and therefore issue spurious DLIs. A $C1 instruction is particularly dangerous as it will
cause a DLI to activate every scan line until vertical blank and can easily cause a crash. Therefore, the display
list pointer should normally only be updated when either display list DMA is disabled or during vertical blank.
However, the routine updates both DLISTH and DLISTL upon a write when (I think) it's only supposed to write the single byte.

Code
//  #define DPAGE           0xfc00  /* 1K page mask for display list */
//  #define DOFFS           0x03ff  /* 1K offset mask for display list */

current code:

Code

void antic_device::write(offs_t offset, uint8_t data)
{
...
	case  2:
		LOG("ANTIC 02 write DLISTL $%02X\n", data);
		m_w.dlistl = data;
		temp = (m_w.dlisth << 8) + m_w.dlistl;
		m_dpage = temp & DPAGE;
		m_doffs = temp & DOFFS;
		break;
	case  3:
		LOG("ANTIC 03 write DLISTH $%02X\n", data);
		m_w.dlisth = data;
		temp = (m_w.dlisth << 8) + m_w.dlistl;
		m_dpage = temp & DPAGE;
		m_doffs = temp & DOFFS;
		break;

and if I change it to only update the part of each byte that's stored in m_dpage and m_doffs:

Code

	case  2:
		LOG("ANTIC 02 write DLISTL $%02X\n", data);
		m_w.dlistl = data;
		temp = (m_w.dlisth << 8) + m_w.dlistl;
		m_doffs = (m_doffs & 0x0300) |  (temp & 0xff & DOFFS);	// keep upper 2 bits of doffs
//		printf("WRITE DLISTL = %x   %s\n",temp,machine().describe_context().c_str());
		break;
	case  3:
		LOG("ANTIC 03 write DLISTH $%02X\n", data);
		m_w.dlisth = data;
		temp = (m_w.dlisth << 8) + m_w.dlistl;
		m_dpage = temp & DPAGE;
		m_doffs = (m_doffs & 0xff) | (temp & 0x300 & DOFFS);  // keep the low 2 bits of DLISTH and or with low byte of doffs
//	printf("WRITE DLISTH = %x   %s\n",temp,machine().describe_context().c_str());
		break;


With this change, Choplifter seems to work just fine.

I don't know if this breaks anything else, but I was super happy to see Choplifter running.
Posted By: Golden Child Re: Atari 800 choplifter - 09/24/21 11:51 AM
And then I was puzzled why enabling tv artifacts causes the screen not to update.

It seems that adding draw_scanline8 after artifacts_txt and artifacts_gfx will do the actual drawing to the screen.

Before, it would just hit the return and not draw anything.

Code

void antic_device::linerefresh()
{
...
	if( m_tv_artifacts )
	{
		if( (m_cmd & 0x0f) == 2 || (m_cmd & 0x0f) == 3 )
		{
			artifacts_txt(src, (uint8_t*)(dst + 3), HCHARS);
			draw_scanline8(*m_bitmap, 12, y, std::min(size_t(m_bitmap->width() - 12), sizeof(scanline)), (const uint8_t *) scanline, nullptr);
			return;
		}
		else
			if( (m_cmd & 0x0f) == 15 )
			{
				artifacts_gfx(src, (uint8_t*)(dst + 3), HCHARS);
				draw_scanline8(*m_bitmap, 12, y, std::min(size_t(m_bitmap->width() - 12), sizeof(scanline)), (const uint8_t *) scanline, nullptr);
				return;
			}
	}

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]
Posted By: Haze Re: Atari 800 choplifter - 09/24/21 12:12 PM
artifacts should really be being done with a shader these days anyway, not in the driver I believe, might be time for that code to go away?

the other video fix sounds reasonable, although I don't know much about the hardware. probably worth making a Pull Request for?
Posted By: Just Desserts Re: Atari 800 choplifter - 09/24/21 12:37 PM
As much as I'd like for per-driver artifacting code to go away, I'm not sure it's time yet.

There are shaders on Windows (HLSL and BGFX) as well as macOS and Linux (BGFX) that will do artifacting if the relevant parameters are "tuned" correctly, but that still leaves out the plain OpenGL backend. And particularly in the case of BGFX, where the user can select whatever shader chain they want - with the artifact-color shader only being available in the HLSL equivalent - it's not even a guarantee in those cases.

Although they got a rough start due to various limitations of both the BGFX library itself as well as some bad assumptions on my part, I believe that the shader-based format conversion now used by the BGFX backend is a good proof of concept that we can engage and disengage shaders based on data that's thrown over the core/OSD fence while preserving the user's ability to select arbitrary chains. MAME's BGFX backend simply bolts the relevant texture conversion shaders on as the very first passes that get run. In theory, the same could be done for an NTSC artifacting shader, just bolt it on as the next pass after texture conversion, and before the user's chosen chain.

However, there's no data there to key off of for either activating or deactivating the NTSC artifacting shader. Additionally, the shader is extremely sensitive to the size of the texture supplied by MAME, hence the need for manual adjustment of certain values in the case of the Apple II driver. So there'd need to be a way of passing those relevant values over as well.

It'll be time for the per-driver artifacting code to go away once that's sorted, but for the time being it's probably better that it remains. Even outside of that, we lack an equivalent PAL-artifacting shader, let alone something crazy like SECAM.
Posted By: R. Belmont Re: Atari 800 choplifter - 09/24/21 01:40 PM
JD's right. I'd very much love automated real NTSC artifacting since e.g. AppleWin has it (although they do it on the CPU), but we're not quite there yet.

Also, yes, please throw this together as a pull request sometime today. It seems like a real fix.
Posted By: Olivier Galibert Re: Atari 800 choplifter - 09/24/21 01:59 PM
Not sure secam artifacting ever happened. France went direct RGB early with the "peritel" plug, so the rf fun stopped early in the secam world.
Posted By: Golden Child Re: Atari 800 choplifter - 09/24/21 05:17 PM
Ok, I made a pull request 8-)

https://github.com/mamedev/mame/pull/8616
Posted By: Golden Child Re: Atari 800 choplifter - 09/24/21 10:33 PM
thanks for the merge, RB!

so far I've found that

Choplifter
david's midnight magic
lode runner
diamond mine
Ultima IV

use the artifact colors

[Linked Image from i.imgur.com]
[Linked Image from i.imgur.com]
Posted By: kmg Re: Atari 800 choplifter - 09/28/21 01:35 AM
I finally tried this. Nice fix on Choplifter, Golden Child! FYI, the BASIC game Crush, Crumble and Chomp! also uses some artifacting.
Posted By: ICEknight Re: Atari 800 choplifter - 09/28/21 10:19 PM
Originally Posted by Just Desserts
Additionally, the shader is extremely sensitive to the size of the texture supplied by MAME, hence the need for manual adjustment of certain values in the case of the Apple II driver. So there'd need to be a way of passing those relevant values over as well.
Wouldn't having MAME always render the full uncropped video output (with the aspect ratio corrected) allow for always sending it the same texture size, for systems that share aspect ratio?
Posted By: =CO=Windler Re: Atari 800 choplifter - 09/29/21 03:40 AM
"Hard Hat Mack" on Atari XL was likely also supposed to do NTSC artifact colours. On my PAL TV it only made an ugly fuzzy B/W texture with blue/yellow flickering hue instead of recognizable colours.
Posted By: Olivier Galibert Re: Atari 800 choplifter - 09/29/21 09:28 AM
Originally Posted by ICEknight
Wouldn't having MAME always render the full uncropped video output (with the aspect ratio corrected) allow for always sending it the same texture size, for systems that share aspect ratio?

Vertically yes, but horizontally the texture width really depends on the pixel clock and that varies.
Posted By: =CO=Windler Re: Atari 800 choplifter - 10/01/21 09:23 AM
In "Zybex" on Atari 800XL there is a flickering line to the left of the screen, and the POKEY music is missing the bass voice! (It happens both in PAL and NTSC Atari, only in NTSC the music plays faster.)

This is what the music should sound like on NTSC (written for PAL, it is originally slower).
Posted By: Reuental Re: Atari 800 choplifter - 03/23/22 02:13 PM
Are there in fact any values known for the artifacting of the Ataris via HLSL/BGFX similar to the Apple II? Or is something to be found out or confirmed to be not possible yet?
Posted By: R. Belmont Re: Atari 800 choplifter - 03/23/22 02:49 PM
I have no idea. I would lean towards "it probably doesn't work" but I don't think anyone's tried either.
Posted By: Just Desserts Re: Atari 800 choplifter - 03/23/22 03:03 PM
There's no reason why it won't work if you can make the Atari driver output pure monochrome, and can manually calculate the necessary values to plug in for the Atari vs. the default NES setup that the default parameters have, same as how other people have calculated the same for the Apple II series.
Posted By: peter ferrie Re: Atari 800 choplifter - 03/26/22 06:45 PM
Originally Posted by Golden Child
so far I've found that

Choplifter
david's midnight magic
lode runner
diamond mine
Ultima IV

use the artifact colors

Aztec's title page might, too. It does for sure on the Apple II.
Posted By: Golden Child Re: Atari 800 choplifter - 03/27/22 04:12 AM
I got interested in fiddling with the NTSC HLSL filter with CGA on the ibm 5150.

It's sort of discouraging to fiddle with since it's very slow on my systems (probably needs a powerful video card). I can speed it up a bit by making the window smaller and setting the frameskip to 10/10.

A little GWBASIC program to make some patterns in 640x200 resolution:

start the ibm5150 with pcdos2 and launch gwbasic with "gwbasic"

Code
90 SCREEN 2 : CLS
100 FOR C=0 TO 15: FOR X=0 TO 150: BAR=10:FOR Y = C*BAR TO (C+1)*BAR: GOSUB 900 :NEXT:NEXT:NEXT
200 LOCATE 20 : END
900 PX0 = X * 4 : FOR PX = PX0 TO PX0+3
910 O = PX - PX0 : PXC = C AND (2^(3-O)) : PSET(PX,Y),(PXC<>0)* -1 : NEXT : RETURN


running this gets you this screen:

[Linked Image from i.imgur.com][Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com][Linked Image from i.imgur.com]

compare to the cga artifact colors given at https://int10h.org/blog/2015/04/cga-in-1024-colors-new-mode-illustrated/

and they are the same colors as the apple ii lo-res colors pattern of 0,4 2,6 1,5 3,7 8,12 10,14 9,13 11,15. (and the same as apple ii double hi-res)

[Linked Image from i.imgur.com]

ntsc a = 0.0
ntsc b = 1.0
scanline duration = 44.7
phase offset = 0.76


running this with Donald Duck's playground:

[Linked Image from i.imgur.com]

Interesting comparisons between the different versions of DDPG at http://frgcb.blogspot.com/2014/04/donald-ducks-playground-us-goldsierra.html
Posted By: Golden Child Re: Atari 800 choplifter - 03/27/22 12:22 PM
Fiddling with the coco2 driver and DDPG:

setting Artifacts to none:

[Linked Image from i.imgur.com]

little bit brighter setting shadow mask to white:
[Linked Image from i.imgur.com]
[Linked Image from i.imgur.com]
Posted By: Golden Child Re: Atari 800 choplifter - 03/27/22 12:40 PM
Okay, so let's try a800 lode runner:

default filter none with artifacts off:

[Linked Image from i.imgur.com]

bgfx filter HLSL NTSC and setting scanline duration to 46.9 usec

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]

and tweaking the carrier a little to match the scanline length makes for more uniform color

If there were another settting to fine adjust the scanline duration with more precision (like .001 usec) that would work also

[Linked Image from i.imgur.com]
Posted By: Golden Child Re: Atari 800 choplifter - 03/27/22 01:02 PM
Experimenting with a800 choplifter

[Linked Image from i.imgur.com]
[Linked Image from i.imgur.com]
Posted By: Golden Child Re: Atari 800 choplifter - 03/27/22 01:56 PM
Can't remember if I tried these before:

Ulysses and golden fleece:

[Linked Image from i.imgur.com]
[Linked Image from i.imgur.com]


setting A and B to 0.0 and phase pixel clock to 2.0 makes the triangle blue and seems to get rid of the banding
[Linked Image from i.imgur.com]
[Linked Image from i.imgur.com]
[Linked Image from i.imgur.com]

trying Ultima

[Linked Image from i.imgur.com]


also Castle Wolfenstein uses artifact colors
Posted By: Dullaron Re: Atari 800 choplifter - 03/29/22 08:22 AM
I like the bright lines and the bright colors.
Posted By: Golden Child Re: Atari 800 choplifter - 03/29/22 12:40 PM
Yes, the white shadow mask is better looking.


I wanted to change the scanline duration in finer increments and it took me awhile to find out which file to change:


Code
grep 'uration' -r src 
src/osd/modules/render/d3d/d3dhlsl.cpp:	{ "NTSC Scanline Duration (uSec)",      0,  52600, 100000, 1, SLIDER_FLOAT,    SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_SCAN_TIME,          0.001f,    "%1.3f", {} },

Code
grep uration -r  bgfx
bgfx/chains/hlsl.json:		{ "type": "float",   "name": "scan_time",       "text": "NTSC Scanline Duration (uSec)",         "default": 52.60,    "max": 150.00,    "min": 1.00,    "step": 0.1,     "format": "%3.1f", "screen": "raster" },

After changing the value in d3dhlsl, running a recompile and it not having any effect, I realized that's because I'm using ubuntu which doesn't use d3d.

The value to change for ubuntu is in bgfx/chains/hlsl.json.


So we just add another digit with step .01 instead of step .1 and change the displayed format from %3.1f to %3.2f

Code
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
{ "NTSC Scanline Duration (uSec)",      0,  5260, 10000, 1, SLIDER_FLOAT,    SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_SCAN_TIME,          0.01f,    "%1.2f", {} },
+       { "NTSC Scanline Duration (uSec)",      0,  52600, 100000, 1, SLIDER_FLOAT,    SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_NTSC_SCAN_TIME,          0.001f,    "%1.3f", {} },


--- a/bgfx/chains/hlsl.json
+++ b/bgfx/chains/hlsl.json

-               { "type": "float",   "name": "scan_time",       "text": "NTSC Scanline Duration (uSec)",         "default": 52.60,    "max": 150.00,    "min": 1.00,    "step": 0.1,     "format": "%3.1f", "screen": "raster" },
+               { "type": "float",   "name": "scan_time",       "text": "NTSC Scanline Duration (uSec)",         "default": 39.60,    "max": 150.00,    "min": 1.00,    "step": 0.01,     "format": "%3.2f", "screen": "raster" },


I also figured out a pretty good workaround for the UI covering up the entire screen. Just use two screens (-numscreens 2) and window mode (-window) and set the second window to be the same as screen 0. (If you only have one screen, they all default to the same screen).

That also allows me to make the second screen's window much smaller to speed up processing.

I wonder if the hlsl could be sped up by processing at the resolution of the driver and then upscaled. So for example the apple ii driver would process at 560x384 and then get upscaled to fit the window.



Apple II example:
Code
100 HGR : FOR C = 0 TO 7 : HCOLOR = C : FOR Y = C * 20 TO (C+1)*20 : HPLOT 0,Y TO 279,Y : NEXT : NEXT

regular mame driver output
[Linked Image from i.imgur.com]

monochrome + hlsl
[Linked Image from i.imgur.com]

Note the scanline duration is now 39.09 (with an additional digit of precision)

[Linked Image from i.imgur.com]


It'd be cool if the slider would allow you change it in a step size of 1 or 10 or 100 by possibly holding down the 2 key for tens and 3 key for hundreds.
Posted By: Just Desserts Re: Atari 800 choplifter - 03/29/22 01:35 PM
Originally Posted by Golden Child
I wonder if the hlsl could be sped up by processing at the resolution of the driver and then upscaled. So for example the apple ii driver would process at 560x384 and then get upscaled to fit the window.

You just described how it already works.

That's how it already works.

The effects that can be run at the guest resolution are already run at the guest resolution. When dealing with passes like scanlines and the shadow mask, you need as much resolution as possible for a pleasing output, so it runs at the host resolution instead.
Posted By: Reuental Re: Atari 800 choplifter - 03/29/22 03:01 PM
Originally Posted by Golden Child
Experimenting with a800 choplifter
I had also had a go at it yesterday before looking at this thread and got David's Midnight Magic to look alright (well I guess in the ballpark), but had problems with Ultima III.
Some other titles that use artifacting (in limited ways) are 221 Bakerstreet and Mr. Do. For Bakerstreet, someone over at the atariage forums provided a shot from real hardware (XL, a pain that the models output differently) some years ago
[Linked Image from i.imgur.com]
Posted By: Golden Child Re: Atari 800 choplifter - 03/30/22 12:32 PM
A little Atari Basic program to make some artifacts for calibration:

[Linked Image from i.imgur.com]

seems like scanline duration is around 46.93

[Linked Image from i.imgur.com]

Mr Do has artifact colors at the top and the bottom of the screen.
[Linked Image from i.imgur.com]

I don't know if those colors are right, it seems that green and purple should be exchanged.

I couldn't get 221b to run.
Posted By: mixmaster Re: Atari 800 choplifter - 03/30/22 01:44 PM

Seems that purple and green should be exchanged.
Posted By: Golden Child Re: Atari 800 choplifter - 04/20/22 01:42 AM
Found a really great game, called "Pondering about Max's". This is a really clever platform game and it runs under the a800xl driver. It's actually a combination of 3 different games, 2 platform games called "The Dream" and "P.A.M.", and beat-em-up called "Barroom Brawl".

[Linked Image from i.imgur.com]


Strangely though in mame's a800xl driver, you can't move laterally on the vertical pipes on the second level of "The Dream".

I can still finish all the levels in "The Dream". Good fun but really difficult.

Supposedly, there's supposed to be a secret on level 1, the clue is "Make the right moves on level 1 of the dream to create PM Madness"... I can jump down onto the billiard balls from the platform above. I think it must have something to do with the banner possibly. I tried jumping on top of the Eggle to jump up to the banner. Who knows, maybe the secret doesn't work on emulators but on real hardware.

[Linked Image from i.imgur.com]

Shortcut on level 7 of the dream, just jump on top of the Eggle in the upper right and use him as a springboard.

[Linked Image from i.imgur.com]

Longplay on youtube:
Posted By: MrBogi Re: Atari 800 choplifter - 04/20/22 01:55 AM
Gotta love the dance the buggles do

Maybe the code in the foot steps on level 4 is a list of the right moves
Posted By: Golden Child Re: Atari 800 choplifter - 04/20/22 11:56 PM
Some fun reads about Pondering About max's:


Review of PAM in Page 6 Magazine:

https://archive.org/details/New_Atari_User_Issue_056_1992-06_Page_6_Publishing/page/n33/mode/2up


Carts that should have been:

https://intotheverticalblank.com/2021/03/28/xegs-carts-that-should-have-been-vol-2/


[Linked Image from i.imgur.com]

Ad for PAM in Start Magazine issue 39 Dec 1990

https://archive.org/details/STart-Magazine-Issue-39/page/n97/mode/2up
Posted By: Golden Child Re: Atari 800 choplifter - 04/21/22 10:49 AM
I'm still perplexed what the "secret" is on level 1 of PAM's The Dream. For fun, I thought I'd see what happens when you poke some of the screen memory with the debugger.

So if I write a bunch of FFs in, I can make horizontal platforms. I'm only putting them in one screen of the double buffer so it flickers and you'll "drop" when it disappears temporarily.
However, it's enough that you'll catch a line while you're falling and you can springboard off of them.

Screen memory for level 1 starts at 1000, around 1870 is into the banner.


[Linked Image from i.imgur.com]

What's actually kind of cool is that poking into the screen memory will affect the path of the billiard balls too.

This also explains why your character drops down when you are standing on the platform and the Eggle moves underneath you, it's changing the screen colors from the color of the platform to another "non-platform" color. This is also why you can "walk" or "jump" on top of the eggle as it has platform colors as part of it.

So after moving all over the screen, I don't think it's tied to your character being on any screen location.
Posted By: Golden Child Re: Atari 800 choplifter - 04/21/22 12:50 PM
Okay, I think I figured it out. If you jump down to the platform where the eggle goes back and forth, then jump on the eggle while moving right, then jump on the spring going right, then there's a glitch which makes a bunch of junk on the screen. I'm guessing that's what's meant by "PM madness" (Player Missile sprites)

This screenshot is from the atari800 emulator under linux (ubuntu):
(I've overlaid the jump sequence)

[Linked Image from i.imgur.com]


This screenshot is from mame after doing the glitch:

[Linked Image from i.imgur.com]

It seems cosmetic and doesn't seem to affect gameplay.

I was trying all kinds of things: jumping down to the stack of pool balls. Trying to jumping on a pool ball in the air. Pulling the switch and trying to get to where the steam pot is before Max shoots up. "Walking" on top of the eggle. Jumping on the eggle and trying to climb on the banner. Jumping up and down on the banner attachments a bunch of times. Trying to pull the switches out of sequence. Trying to jump down on the banner where it has a band in the word TD since it looks like a platform. Trying to "catch" the banner while falling and pressing the jump button.




Posted By: kmg Re: Atari 800 choplifter - 04/21/22 08:05 PM
FYI, Pondering About Max's has been added to the software list.
Posted By: Golden Child Re: Atari 800 choplifter - 04/21/22 08:30 PM
Awesome! Thanks, kmg!

[Linked Image from i.imgur.com]

© Forums