Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by ZackAttack

  1. I've been toying around with building my own PCB for the 2600 and I've noticed that the price difference between ENIG gold fingers and hardened gold is quite a bit. Especially in low volumes. Does anyone know if there are existing cart PCBs that have used ENIG for the gold fingers plating and how well they have held up? My concern is that ENIG might seem to work fine for the first couple of years, but will eventually have corrosion or wear problems that only show up after years of service.
  2. I just added a permissive license to the strong arm repo. I think that's necessary since most will want to modify something and include it with their games. Unocart firmware has a license on github as well: https://github.com/robinhedwards/UnoCart-2600/blob/master/LICENSE It's worth noting that although the unocart is the only hardware that currently supports this framework, the plan has always been to have a stripped down cheaper cart for publishing games. In that scenario the unocart licensing wouldn't apply since strong arm can bootstrapped directly without going through the uno firmware.
  3. It's been a while since I've played with that, but if I recall correctly. There were two types of failures with the early bus stuffing attempts. The first type was when the cart failed to stuff its value onto the bus. The other type was timing related. Some systems, mine in particular, have some unusual address bus activity in the transition time between valid bus signals. The timings are compliant with the 6502 datasheet as far as I can tell. The problem is that the carts don't have access to any clock signals and have to poll the address bus to determine which rom location to emulate or which address location its stuffing a value into. If a transient value is identified as the next location, the cart will produce the wrong value and probably spend too much time doing so to catch the actual value that follows. I completely bypass this problem in the strong-arm framework by keeping track of where 6502 will be reading next, precalculating the corresponding value, polling for the specific address value, and posting the data onto the bus as soon as the expected address is present on the bus. This has the bonus side effect of leaving more time to do useful work on the ARM core between 6502 bus servicing.
  4. Have you ever tried out this other bus stuffing implementation demo on that problematic junior?
  5. If you look at the unocart firmware you'll find that it's already writing to the flash memory for the larger schemes like 3E when the bin is too big to fit in RAM. So just use that as a template to add flash memory writing support to your own arm project. I think it would be good if we reserved sector 3 for saved game data and defined a simple structure to allow multiple games to share it. It would also be nice to add import/export functionality to the firmware so you could backup to SD or share your games saves. Though if you only care about a stand alone cart, you could use whatever sector you want, any way you want.
  6. Assuming you are referring to the values that are at those locations after power on reset. The firmware would need to be enhanced to restore the original RAM values before handing execution over to the ace file. The current firmware overwrites all the TIA RAM on startup and discards the original values. Might be worth posting something in the official firmware thread.
  7. vcsWrite3() is a WIP implementation of bus stuffing. I plan to implement error detection and correction to account for some systems that have been problematic in the past. When it's done there will be a routine provided that does the error detection and provides the masks and values needed for A, X, and Y. Then vcsSetMasks() would be called during initialization and vcsLd*() would be called for A, X, and Y prior to using vcsWrite3(). Write3() will select STA, STX, STY, or SAX depending on the value being stuffed so that only 6 of the 8 bits need to be overridden by the ARM chip. Which 2 bits aren't stuffed will depend on the results of the error detection.
  8. The ACE file format is used to update the unocart firmware. ACE compatibility is part of the required testing for unocart firmware releases. It's safe to assume that ACE will continue to be supported on unocart. The c/c++ framework itself is pretty self contained and could even be used with other hardware solutions as long as the microcontroller has enough resources. Stella is the main thing you need to take into consideration. For development purposes I have a fork of the stella source that can run ACE/Strong-ARM games. The way this is done is only suitible for development purposes though. I wouldn't expect stella to support this new format until there were enough games released to make it worth while. TLDR; if you use this framework you should expect your game to only be playable on unocart. The entire tech stack is open source. That should minimize the risk of developing for a platform that gets abandoned. If you provide more details about exactly what you're planning on building. I'd be happy to provide more details about how well suited this framework would be.
  9. That's great. I can take care of building a new firmware updater with the new firmware once you're done and also with testing everything.
  10. Have you tried generating a log of all the bus activity while the game is running? I think if you posted a log you'd get some help with figuring out how the customized chip works. You could hack together a data logger with an uno-cart and a Y adapter. Customizing the uno-cart firmware to be a datalogger is fairly trivial and a Y adapter would just require a few connectors, a donor pcb and some patience to solder everything.
  11. You could also position the first copy far enough right so the second copy wraps around to the left side of the screen.
  12. Keep in mind the peripheral clock is typically slower than the core CPU clock. You're correct though. It's possible to get a stable address that is not the next actual address. In practice this isn't really an issue because it's no different than having a really fast rom. There will be some transient values driven on the data bus while the address settles down, but eventually the correct address/data pair are produced and because there's a considerable delay between when the address is valid and the data is read it's always sorted itself out in time. The one exception to this is pitfall 2 because a lot more processing is done for each address and sometimes this can trip it up. I made a custom firmware build that logged the stable addresses to SD card when we were troubleshooting an issue with a specific system. On my 2600 jr it would pick up at least one wrong address for every right address. You could poll for longer but the problem with that is it increases latency and could lead to a failure to service the data bus in time. To get around this problem and allow useful work to be done in place of the address polling I keep track of what the next ROM address would be and wait for the address bus to be set to that before proceeding to update the data bus. This allows the data value to be calculated in advanced and also eliminates servicing any transient address values. The only downside is that you have to emulate enough of the 6502 to know which rom address comes next. For my purposes it's not difficult since I run all my game logic in ARM and only use a few load/store instructions to update the TIA registers. That project is also open source.
  13. Why don't you start posting some graphics? If you provide some screen mockups you'll get feedback on what is and isn't possible with a classic 4/8k game. You'll have a better chance at recruiting programmers or programming it yourself if the game design is well documented and properly matched to the 2600 limitations.
  14. I posted a separate topic with bin herehttp://atariage.com/forums/topic/279712-raycasting-with-bus-stuffing-demo/?fromsearch=1
  15. Exactly. What's involved in making a faithful port is fundamentally different than making an original game. This is why I think ports deserve their own category. Separating them does not imply that either approach is better or easier.
  16. I'd actually argue the other direction for categories. Instead of adding one for 4k/assembly the bB category should be removed. Either it's a fun game to play or it's not. Who cares how it was built. A better category would be for ports/demakes since the game design effort is mostly provided by the original IP.
  17. You can find a fully working example of this in the Collect Tutorial. A 2 byte variable is created to hold the pointer to the human graphics. ORG $80 HumanPtr: ds 2 ; used for drawing player0 The address of the graphics to point to is calculated and stored in HumanPtr. Note that since this is a 2 byte pointer variable the low byte is stored at HumanPtr and the high byte is stored at HumanPtr+1. ; HumanPtr = HumanGfx + HUMAN_HEIGHT - 1 - Y position lda #<(HumanGfx + HUMAN_HEIGHT - 1) sec sbc ObjectY sta HumanPtr lda #>(HumanGfx + HUMAN_HEIGHT - 1) sbc #0 sta HumanPtr+1 Indirect Y addressing is used to load a byte from the array stored at the location pointed to by HumanPtr with the index/offset specified by Y. lda (HumanPtr),y ; 5 28 - load the shape for player0
  18. Sure. It's probably better to ask a more specific question when you get there though. The general idea would be to have a label followed by some ROM data and then use LABEL,X as the addressing mode. If you need another level of indirection it may be necessary to go with (),y. In which case you'd have multiple arrays in ROM and a 2 byte pointer variable in RAM. You'd copy the pointer to RAM for the desired array before the loop and then use (POINTER_VAR),Y inside the loop.
  19. If you intend on ORing 64 with each of them you would want to use the immediate mode for the ORA instruction. As far as indexing the different virtual sprites, that would depend on how they are laid out in memory. If they are all sequential in a chuck of contiguous memory there is no need for _byte. There are several ways to go about this, but I'd expect it to look something like this: SEG.U VARS ORG $80 NUSIZ_ARRAY ; Multiple labels at same address since both the array and NUSIZ0 are located starting here NUSIZ0 ds 1 NUSIZ1 ds 1 NUSIZ2 ds 1 ; Set bit $20 for NUSIZ0-NUSIZ2 LDX 2 ; start with NUSIZ2 and work back to 0 Loop: LDA NUSIZ_ARRAY,x ORA #64 STA NUSIZ_ARRAY,x DEX BPL Loop
  20. The UnoCart has support for ACE which is another scheme that allows game code to be offloaded to the ARM core. DPC+ and CDF are currently capped at 32kb rom and 8kb ram. ACE supports 448kb of rom and 192kb ram. On the flip side there are many quality homebrews which have already been released for DPC+ and CDF as well as some excellent documentation for developers. ACE is still largely undocumented and there is currently only a single game in development for it. I'd recommend getting both carts if you can afford it.
  21. Perhaps I'm missing some critical details to properly answer your question, but couldn't you just substitue any 5V parallel SRAM chip? I did a quick search on digikey and found a bunch for under $4 (USD). Sure they have much more than 128 bytes. Just limit how much of it you actually use in your implementation.
  22. I haven't heard anything other than what was posted in this thread. If you're getting a lot of dpc failure reports with the current version it would probably be worth moving to the latest. Otherwise I'd probably just stick with what you've been using and direct anyone with dpc issues to the experimental version. Some time in the near future I plan on making another build available that will address a very rare problem with JRs and another issue that appears to be related to the startup speed of the cart.
  23. Can't you just use a melody/harmony or unocart? Either one can be flashed as a standalone cart and they both should support whichever bank scheme you want to use.
  24. Off the top of my head without testing or optimizing I think something like this would work: ; pet movement code lda PetX clc adc PetVX sta PetX cmp #LEFTBOUNDRY bcc ReversePetDirection ; PetX < 20 cmp #RIGHTBOUNDRY bcs ReversePetDirection ; PetX > 144 jmp SkipReversePetDirection ; 20 < PetX && PetX < 144 ReversePetDirection: lda PetVX eor #$ff clc ; must clear carry because it's set or cleared depending on which boundary violation got us here adc #1 sta PetVX ; TODO This would be a good place to toggle the reflection flag if Pet has a directional sprite SkipReversePetDirection Regarding your solution, I think the first adc #0 should actually be adc #1 since the carry flag would need to be cleared to take that code path. If you find that the pet is speeding up each time it crosses the screen twice, that's why. Personally I'd probably just clc before every adc operation until you have a need to start optimizing. Even then you'll probably find better places to start optimizing (low hanging fruit). Hope that helps. -Zack
  25. Still feels wrong to me. If your position is 155 you are greater than 20 and branch past the reversedirection code as well as the second check for the right-boundary condition. In a higher level language I think you've created this: if(x < 20) { if(x > 144) { ReverseDirection(); } } But what you really want is this: if((x < 20) || (x > 144)) ReverseDirection(); Or with the logic inverted: if(!(20 < x && x < 144)) ReverseDirection();
  • Create New...