Nukey Shay Posted September 24, 2010 Share Posted September 24, 2010 (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. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted September 24, 2010 Share Posted September 24, 2010 Happen to know any games offhand that use VDELBL? Halo 2600, Meltdown, Pitfall 2, Laser Gates, Polaris, Decathlon, Crossbow Quote Link to comment Share on other sites More sharing options...
+batari Posted September 24, 2010 Share Posted September 24, 2010 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. Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 24, 2010 Author Share Posted September 24, 2010 (edited) 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 September 24, 2010 by DavidEth Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 24, 2010 Author Share Posted September 24, 2010 (edited) Here's a prebuilt executable. No warranties, etc, scan it with a virus checker, etc. I believe my system is clean but you never know. Includes SDL.DLL from version 1.2.14. EDIT - Fixed help text, only 2k and 4k roms work. -Dave my2600w32.zip Edited September 24, 2010 by DavidEth Quote Link to comment Share on other sites More sharing options...
RevEng Posted September 24, 2010 Share Posted September 24, 2010 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. Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 24, 2010 Author Share Posted September 24, 2010 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 Quote Link to comment Share on other sites More sharing options...
RevEng Posted September 24, 2010 Share Posted September 24, 2010 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 Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 24, 2010 Author Share Posted September 24, 2010 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 Quote Link to comment Share on other sites More sharing options...
+stephena Posted September 24, 2010 Share Posted September 24, 2010 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. Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 24, 2010 Author Share Posted September 24, 2010 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 Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted September 24, 2010 Share Posted September 24, 2010 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. Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 24, 2010 Author Share Posted September 24, 2010 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 Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted September 24, 2010 Share Posted September 24, 2010 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. Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 24, 2010 Author Share Posted September 24, 2010 (edited) 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 September 24, 2010 by DavidEth Quote Link to comment Share on other sites More sharing options...
+batari Posted September 24, 2010 Share Posted September 24, 2010 Hardware has a polynomial counter instead of comparators. I don't know exactly how it works but I believe it's described here: http://www.atarihq.com/danb/files/TIA_HW_Notes.txt Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 24, 2010 Author Share Posted September 24, 2010 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 Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 25, 2010 Author Share Posted September 25, 2010 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 Quote Link to comment Share on other sites More sharing options...
raindog Posted September 25, 2010 Share Posted September 25, 2010 Builds and runs fine under Ubuntu Karmic using gcc `sdl-config --cflags --libs` -lstdc++ -o my2600 my2600.cpp Really sweet for a 3-day-old emulator. Great work. Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 25, 2010 Author Share Posted September 25, 2010 (edited) 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 September 25, 2010 by DavidEth Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted September 25, 2010 Share Posted September 25, 2010 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. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted September 25, 2010 Share Posted September 25, 2010 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. Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 25, 2010 Author Share Posted September 25, 2010 (edited) 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 September 25, 2010 by DavidEth Quote Link to comment Share on other sites More sharing options...
DavidEth Posted September 25, 2010 Author Share Posted September 25, 2010 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 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted September 25, 2010 Share Posted September 25, 2010 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 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.