Previous Thread
Next Thread
Print Thread
Page 1 of 2 1 2
#119717 09/24/21 01:18 AM
Joined: Feb 2014
Posts: 674
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 674
Likes: 9
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.

Joined: Feb 2014
Posts: 674
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 674
Likes: 9
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]

Joined: May 2004
Posts: 1,676
H
Very Senior Member
Offline
Very Senior Member
H
Joined: May 2004
Posts: 1,676
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?

Joined: May 2009
Posts: 1,965
Likes: 23
J
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 1,965
Likes: 23
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.

Joined: Mar 2001
Posts: 16,808
Likes: 32
R
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,808
Likes: 32
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.

Joined: Jun 2001
Posts: 461
O
Senior Member
Offline
Senior Member
O
Joined: Jun 2001
Posts: 461
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.

Joined: Feb 2014
Posts: 674
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 674
Likes: 9
Ok, I made a pull request 8-)

https://github.com/mamedev/mame/pull/8616

Joined: Feb 2014
Posts: 674
Likes: 9
G
Senior Member
OP Offline
Senior Member
G
Joined: Feb 2014
Posts: 674
Likes: 9
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]

Joined: Apr 2021
Posts: 16
Likes: 2
K
kmg Offline
Member
Offline
Member
K
Joined: Apr 2021
Posts: 16
Likes: 2
I finally tried this. Nice fix on Choplifter, Golden Child! FYI, the BASIC game Crush, Crumble and Chomp! also uses some artifacting.

Joined: Mar 2013
Posts: 328
Likes: 1
I
Senior Member
Offline
Senior Member
I
Joined: Mar 2013
Posts: 328
Likes: 1
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?


LCD artwork scans and cleanups: https://mega.nz/#F!uFYSzK7S!U-lJon9jsqyoCX_3y7_KLA
Page 1 of 2 1 2

Link Copied to Clipboard
Who's Online Now
2 members (Duke, Dorando), 24 guests, and 2 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,974
Posts117,896
Members5,001
Most Online890
Jan 17th, 2020
Forum Host
These forums are hosted by www.retrogamesformac.com
Forum hosted by www.retrogamesformac.com