Jump to content
IGNORED

Getting the thin red line to just draw at the leftmost position.


GradualGames

Recommended Posts

I'm tinkering with Atari 2600 101 and, I'm understanding things fairly well already being well versed in 6502, but understanding the Atari 2600 itself is where I think I will need some help.

 

I understand that the position of objects are strongly coupled to the actual position of the currently scanning line, where it is both horizontally and vertically. I understand vertical position is set by enabling/disabling the various objects on the scanlines on which you want them to be present. I also understand there are several "reset" registers which can set the coarse horizontal position.

 

So as a first experiment I thought I'd just try to get the "thin red line" program to draw the line at the leftmost position, by setting one of the reset registers. I believe that missile 0 is what forms the red line, is that correct? Therefore I'd expect to be able to place it at the leftmost part of the screen by doing this:

 

lda #0

sta RESM0

 

right after a WSYNC. However my initial experiments with this register don't appear to be doing anything, the line stays where it is (about 1/3 into the screen, from the left). I was able to change the horizontal move register to just be 0 so the line does not animate.

Edited by GradualGames
Link to comment
Share on other sites

This one?

http://atariage.com/2600/programming/2600_101/03first.html

 

It should work as expected (you don't need the "LDA #0", anyway. RESxx are strobe register, the actual value you write is irrelevant, it only matters when the write occurs)

Just ensure to put that code after the "ClearMem" loop, as that clears all ram and TIA registers (so it strobes RESM0 too!)

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

The reset registers are confusing at first. You don't store the desired X position into them. They are only strobe registers, like WSYNC, so the value isn't even used.

Each object has a position timer that waits for exactly 1 scanline, and then draws the object if it is enabled, over and over. Writing to an object's reset register (with any value) resets that object's position timer, which changes the object's horizontal position on the screen. If you want to position an object in the center of the screen, you have to wait until the electron beam reaches the point of the screen you want to place the object, and then reset the player's position. (You also have to account for the 3 cycles it takes to write to the register.)

As an example, you could write to WSYNC, which waits until the end of the scanline, wait 30 cycles, and then write to RESM0 (which resets the position at cycle 33, NOT cycle 30). This would put the missile left of center. If you modified the code to wait longer, the missile would move to the right.

Keep in mind that the first 22.67 cycles of a scanline are part of horizontal blanking, and are not on the visible screen. If you write to RESM0 during horizontal blanking, the object will be placed on the left edge of the screen.

 

I'm not sure if you have read it yet, but the Stella Programmer's Guide is very informative about the hardware. Just keep in mind that the manual only tells you how 2600's designers intended it to be used, so it doesn't talk about all the special tricks you can do that weren't known at the time.

Edited by JeremiahK
Link to comment
Share on other sites

Your reasoning seems sound. Try posting your code. Also, horizontal motion is a little buggy. Maybe you violated one of the following:

 

8.0 Horizontal Motion

 

There are timing constraints for the HMOVE command. The HMOVE command must immediately follow a WSYNC (Wait for SYNC) to insure the HMOVE operation occurs during horizontal blanking. This is to allow sufficient time for the motion registers to do their thing before the electron beam starts drawing the next scan line. Also, for mysterious internal hardware considerations, the motion registers should not be modified for at least 24 machine cycles after an HMOVE command.

 

Also try commenting out the HMOVE. Sounds like you don't need it.

Edited by BNE Jeff
Link to comment
Share on other sites

Your reasoning seems sound. Try posting your code. Also, horizontal motion is a little buggy. Maybe you violated one of the following:

 

 

I wouldn't call it buggy, and it is certainly not mysterious ;) Quoting my explanation of the mechanism from another thread:

 

Strobing HMOVE will raise a flag that causes horizontal blanking to be extended by 8 color clocks. Each sprite is essentially a counter that is not clocked during hblank, and so this will effectively move the sprite 8 pixels to the right (as it will take 8 more color clocks until the counter reaches the value that triggers rendering); the side effect are the black lines.

In order to facilitate other movement values, strobing HMOVE will trigger the TIA to start sending extra clock pulses that will drive the sprite counters. The amount of pulses that is sent to each sprite depends on the value of the high nibble of HMXX. The highest bit is internally inverted, so a value of 0 will cause 8 extra clocks, amounting to zero movement, 7 will cause 15 extra clocks, amounting to 7 pixels movement to the left.

During the visible part of the scanline, the extra clocks will interfere with the regular clock pulses. The details depend on the exact TIA revision; it is assumed that, on most chips, the extra clocks fall together with the regular ones and have no effect at all. Either way, this is the reason for the timing restrictions on HMOVE.

At the end of the scanline, the flag that prolongs hblank is cleared. If you strobe HMOVE before this, the extended blanking will not happen, and all extra clocks will cause a shift of one pixel to the left. This is the reason for the idiosyncrasies of late HMOVE. If you strobe HMOVE before the line ends **and** before the first extra clock is sent, you can achieve 15 pixels of movement to the left this way.

On a sidenote, this also explains most of the starfield effect: If you write HMxx while the extra pulses are sent, you can set it to a value below the extra pulse counter **before** the stop condition has been reached. This will cause the sprite to receive extra clocks until the next HMOVE and causes the starfield :)

  • Like 1
Link to comment
Share on other sites

Not sure exactly what was wrong earlier. I think the problem was I needed to put the STA RESM0 in the scanline loop itself. Now the line shows up on the left. It's actually a couple of pixels tucked in from the extreme left of the screen though. Not sure if it's possible to make it flush against the left side (using Stella) or if there's always a bit of a bar there on the left?

Edited by GradualGames
Link to comment
Share on other sites

RESM0 doesn't need to be in the kernel. In fact, you typically do them outside to free up kernel time- which you can certainly do here. Nonetheless, it looks like placement was your issue. Hacking Kirk Israel's Thin Red Line.. I remember..

 

Don't be afraid to post your original asm. Someone will tell you exactly what was happening.

 

Have you acquired Stella Programmer's Guide?

Edited by BNE Jeff
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...