Jump to content
IGNORED

INTIM issue in Berzerk?


DavidEth

Recommended Posts

(Regular) Breakout does, but it would probably be difficult to notice the difference.

 

Why not just write something that uses problem or questionable registers? Easier than jumping from game-to-game in the first part of testing...and there are plenty of demo kernels around to add junk into. Once a demo is working the way that you expect it to (or rather, how they are supposed to), move on to checking actual game roms.

Link to comment
Share on other sites

For the ball, there is the ENABL register, so just think if this as having two values, and is triggered by a write to GRP1.

 

Happen to know any games offhand that use VDELBL? Combat is still pretty flaky -- can't get the bullets to fire reliably and while the tanks show up, the planes only flicker briefly.

 

Laser Blast is kinda funny too -- the enemy shots work fine but your laser is invisible even though it still destroys things.

 

EDIT - Turns out the ladder in Pitfall is implemented with the ball, so I was able to use it as a test case.

 

-Dave

Combat missiles could be due to the PHP instruction. PHP pushes flags to the stack, which is mirrored on top of RIOT RAM but also TIA registers. Combat sets the stack pointer to point to an ENAMx mirror, and the Z flag happens to be bit 1 which enables the missiles in Combat. Not sure why the planes aren't showing up.

Link to comment
Share on other sites

Thanks for reminding me about Halo 2600 -- hearing about that game (and how he was inspired by reading Racing the Beam) was what inspired me to finally start digging into 2600 programming in the first place.

 

The title screen isn't quite right -- only two of the stars show up, and there's a gap missing between the A/L and 6/0 which is probably something I'm doing wrong with the playfield registers. In the game itself, my dude can't fire for some reason although the enemies can. There's also some weird horizontal motion problem.

 

Anyway, I slapped together a source release if anybody's curious what a three-day-old atari emulator looks like. No sound, and no executable. Displays Requires SDL. Should compile and run on any 32 or 64 bit system with SDL. Only supports 2k and 4k roms at present, NTSC only although PAL support should be trivial to add (need a new LUT and a different screen height).

 

Pitfall works pretty well -- only problem I see is a one pixel gap in the copyright string. Space Invaders is playable, as is Adventure.

 

EDIT - Fixed help text, removed temporary "should HMOVE also do an XMCLR" test code.

 

-Dave

my2600src.zip

Edited by DavidEth
Link to comment
Share on other sites

In the game itself, my dude can't fire for some reason although the enemies can.

Did you grab the gun? Its 1 screen up from your starting position.

 

Duh, I'd forgotten about that. On the other hand, it still didn't work, and the player gets split in half and has weird collision issues at the right edge of the screen.

 

In Combat, the planes do show up until they go off the right-hand edge of the screen, so I'm probably not handling horizontal motion correctly when something is off an edge of the screen.

 

-Dave

Link to comment
Share on other sites

I took a quick look at your source, and I don't think you're allowing for non-standard HMOVE timing, are you?

 

If HMOVE is hit early or late it changes the distance objects are moved via the HM registers. Check out: http://www.bjars.com/resources/hmove.txt

 

How do I read that table? Are those TIA cycles or CPU cycles? Are they relative to the start of HBLANK? Presumably the write happens on the last cycle of the instruction.

 

My emulator starts a scanline at pixel -68 and starts rendering at pixel zero. Hitting WSYNC delays the CPU until cycle -68.

 

-Dave

Link to comment
Share on other sites

I took a quick look at your source, and I don't think you're allowing for non-standard HMOVE timing, are you?

 

If HMOVE is hit early or late it changes the distance objects are moved via the HM registers. Check out: http://www.bjars.com/resources/hmove.txt

Even that table doesn't cover all cases, though. There are quite a few ROMs that do 'illegal' HMOVE handling. That is, HMOVE is strobed when it isn't 'supposed' to be (as defined in the Stella programmers guide). Detecting and handling this case isn't simply a case of creating a lookup table. In fact, none of the current emulators support this fully (Stella, z26, MESS, etc), and they've been worked on for years. If you manage to come up with a quick, concise, and easy to understand way of handling all HMOVE irregularities, then I'd love to add it to Stella.

Link to comment
Share on other sites

What do RESMP0/1 actually do? Docs say if the bit is nonzero, the missile will remain locked to the center of its player and missile graphics will be disabled.

 

Why is this register even here? What purpose does it serve that simply hitting ENAM0/1 instead would do?

 

Right now my emulator uses the following logic at the beginning of a scanline:

 

m0_start = ((tia_state[ENAM0] & 2) & (tia_state[RESMP0] ^ 2)) ? m0_start_next : -999;

 

meaning that ENAM0 has to be on, and RESMP0 has to be off or else the missile counter will be loaded with an impossible value. m0_start_next remembers the current TIA cycle when you last hit RESM0. When the missile is set in this way, does it still participate in collisions?

 

-Dave

Link to comment
Share on other sites

I gather that it was just a shortcut. It automatically resets the missile position to the center of the player (i.e. firing a gun) AND hides the missile...perfect for avoiding Px/Mx collisions just as it is being fired, or suffer the consequence of being destroyed by your own shot if missile collisions are treated indescriminate. The Stella guide states this:

 

As long as Bit 1 is set, the missile is hidden and its horizontal position is centered on the players position. The centering offset is +3 for normal, +6 for double, and +10 quad sized player (that is giving good centering results with missile widths of 2, 4, and 8 respectively).

 

Once set, later HMOVE's will handle horizontal motion from the firing spot automatically if data exists in the corresponding register for the missile. Saves a step of otherwise having to strobe RESMx.

Link to comment
Share on other sites

Once set, later HMOVE's will handle horizontal motion from the firing spot automatically if data exists in the corresponding register for the missile. Saves a step of otherwise having to strobe RESMx.

 

That's got me thinking -- so do some games not even bother to remember the horizontal position of certain things like missiles? Seems like you can use HMOVE over and over on each scanline to adjust the existing position, and then you just pay attention to the collision registers to see if you hit anything. Of course you still need to remember the vertical position.

 

Also, that does hint at what might be going wrong -- games would assume the missile already has a valid horizontal position even when it's hidden, so I think I need to rework my logic there a bit.

 

-Dave

Link to comment
Share on other sites

That's got me thinking -- so do some games not even bother to remember the horizontal position of certain things like missiles? Seems like you can use HMOVE over and over on each scanline to adjust the existing position, and then you just pay attention to the collision registers to see if you hit anything. Of course you still need to remember the vertical position.

 

That's basically how Pong-type and shooting games usually function. No resources required to keep track of a ball/bullet's horizontal position...just alter HMxx or kill it when collisions are detected.

Link to comment
Share on other sites

So I implemented the RESMP0/1 processing, and Combat still wouldn't work, checked a bunch of other things (PHP working as expected, etc) and finally figured out that I'd screwed up my new logic and the missile was only being reset to the player for the first scanline, after which it was incorrectly inheriting a stale timer value that (because it was just a normal 32 bit C integer) would increment up into oblivion quickly.

 

However, I am seeing that driving or flying off the right edge of the screen is causing objects to disappear permanently.

 

What does the hardware do with the motion counters if HMOVE decrements them below zero or increments them above 160? Does it wrap immediately? I don't remember seeing any comparators in any block diagrams I was looking at.

 

EDIT - If I modify my HMOVE handling to add 160 if it falls below 0 and subtract 160 if it reaches or exceeds 160, things get better but it's still not quite correct. Also, what happens if RESP0 is hit during horizontal blank? I'm assuming it would reset the motion counter to zero, although there does seem to be a 5/6 cycle delay for missiles/players respectively.

 

Thanks again,

 

-Dave

Edited by DavidEth
Link to comment
Share on other sites

Updated version of source code.

 

Since last upload:

 

1. Really crude debugger implemented. Run with no args to see cmd line help; can break on code address or writing to a location.

2. Disassembly available from command line; disassembles all 4k even for a 2k rom. Both numeric and symbolic addresses show for ZP addres.

3. Implemented RESMP0/1, which fixes missiles not working in Combat.

4. Cleaned up horizontal motion logic, and have it magically wrap at 0/160; fixes objects going off the left/right edge and never coming back.

 

On a side note, it seems like when a plane starts to fly off the right edge in Combat, when it's rendered with wrap around it's actually one scan line lower. Not sure if real hardware does that or not.

 

River Raid also works pretty well, although it demonstrates the pixel gaps in the fuel gauge, and the fuel meter seems to be pegged to the plane's horizontal position.

 

-Dave

my2600src.zip

Link to comment
Share on other sites

Can't edit the original post, so another version.

 

DDRB properly implemented. Fixed typo that would screw up ball motion adjust. Fixes helmet on Halo 2600, although I can't seem to go off the right edge at all any more.

 

Besides sound, I know I also don't implement multiple copies of the missile when the player is being copied. Also, hitting RESP0 on the same scanline (Galaxian, Space Instigators, among others, I think) won't work properly yet.

 

-Dave

my2600src.zip

Link to comment
Share on other sites

Another quick update, added 8k rom support (F8 method). The docs I could find said that reading from 1FF8/1FF9 were sufficient, but the first cart I tried (Galaxian) only wrote to those addresses, so I implemented the switching only on writes.

 

Anybody know of a cart that does F8 switching but only via reads? Supporting it properly won't be that difficult, I just need to remember it's an 8k cart and treat reads from $?FF8/9 specially in that case. EDIT - Of course right after posting the very next cart I decided to try, Raiders of the Lost Ark, uses F8 method via reads, so I implemented it properly.

 

-Dave

 

ps Galaxian and Phoenix are both playable now. Galaxian is tricky since I don't yet correctly emulate the multiple sprite trick it uses.

my2600src.zip

Edited by DavidEth
Link to comment
Share on other sites

Raiders Of The Lost Ark and E.T. (a couple of the most-common games out there) use only LDA's to trigger the hotspots. AFAIK, the earlier games like Asteroids, Ms.Pac, use STA's.

 

The method should be ambiguous, tho. There are some that use BIT, but I can't recall them offhand. And of course, a homebrew might be using triple-NOP's.

Link to comment
Share on other sites

Also, there's at least one that uses the registers as a means of "remembering" which bank it was called from (as in LDA $FFF8,X)...but I can't recall what it was or if it was larger than 8k. I know that Midnight Magic does this in 16k...but I think that I've run across it before in a smaller one.

Link to comment
Share on other sites

While trying to get carts with extra ram to work, I ran into a bizarre problem on Stargate that turned out to be a typo in the STA/X/Y $WWWW,X opcode -- it was accidentally using y to compute the offset instead of X.

 

Strangely, it seems like no other cartridges I'd tested used that particular addressing mode, which I guess makes sense because the vast majority of stores will be to zero-page addresses on a non-RAM-extended ROM.

 

Stargate is getting pissed off waiting for RIOT $285 to go negative though. Only docs I could find indicate it is some sort of interrupt level trigger setting, but I didn't think the 2600 even had interrupts? EDIT - I just hacked reads of $285 to return #$FF instead of zero, and Stargate is playable now.

 

Mountain King (12k cart with 256 bytes of RAM) now seems quite playable.

 

-Dave

my2600src.zip

Edited by DavidEth
Link to comment
Share on other sites

A timing question -- if I do a STA WSYNC, then the next instruction will start on color cycle -68 of the next scanline (or color cycle 160 of the current scanline, they're equivalent, right).

 

So code like the following:

STA WSYNC
; we're now on the first cycle of HBLANK, 76 cycles total available now
REPT 23
 STA DUMMYPAGE0
ENDREPT ; 69 cycles
NOP ; 2 (71 total)
NOP ; 2 (73 total)
STA WSYNC ; 3 (76 total)

 

Will that second WSYNC take 3 cycles or 79 cycles? If I replaced the two NOP's with a three-cycle insn, would the WSYNC take 4 cycles? If I added an additional NOP, I assume the STA WSYNC would definitely miss the current HBLANK and take 78 cycles to finish?

 

-Dave

Link to comment
Share on other sites

A timing question -- if I do a STA WSYNC, then the next instruction will start on color cycle -68 of the next scanline (or color cycle 160 of the current scanline, they're equivalent, right).

 

So code like the following:

STA WSYNC
; we're now on the first cycle of HBLANK, 76 cycles total available now
REPT 23
 STA DUMMYPAGE0
ENDREPT ; 69 cycles
NOP ; 2 (71 total)
NOP ; 2 (73 total)
STA WSYNC ; 3 (76 total)

 

Will that second WSYNC take 3 cycles or 79 cycles? If I replaced the two NOP's with a three-cycle insn, would the WSYNC take 4 cycles? If I added an additional NOP, I assume the STA WSYNC would definitely miss the current HBLANK and take 78 cycles to finish?

3 cycles, 4 cycles, 78 cycles

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