Thread Like Summary
Dullaron, Reuental
Total Likes: 3
Original Post (Thread Starter)
#119717 09/24/2021 1:18 AM
by Golden Child
Golden Child
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.
Liked Replies
#120636 Mar 23rd a 03:03 PM
by Just Desserts
Just Desserts
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.
1 member likes this
#120659 Mar 27th a 01:56 PM
by Golden Child
Golden Child
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
1 member likes this
#120658 Mar 27th a 01:02 PM
by Golden Child
Golden Child
Experimenting with a800 choplifter

[Linked Image from i.imgur.com]
[Linked Image from i.imgur.com]
1 member likes this
Who's Online Now
2 members (Pernod, 1 invisible), 21 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
Topics9,086
Posts119,088
Members5,014
Most Online890
Jan 17th, 2020
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Forum hosted by www.retrogamesformac.com