Jump to content

About This Club

The little box that saves and talks! This club is meant to serve as a central location for information about AtariVox programming: creating and incorporating voices into homebrews, and using it to save and load game data (high scores, game progress and other settings).

  1. What's new in this club
  2. 64 bytes, according to the manual.
  3. Thanks, I figured it would have something to do with the READY pin. I wouldn't want actual speech playing the detection phase so I assume I could fill in the buffer with a bunch of control commands (ie. loop setting the PITCH over and over and see if RDY ever drops to 1). Do you know how big the buffer?
  4. What about sending some long enough speech data and check if the READY pin (pin 2 of the controller port, that is SWCHA bit 1/bit 5 for the right/left port respectively) ever reads as 0, indicating that the Speakerjet buffer is full? On a SaveKey that pin should be unused (floating) and always read as 1.
  5. Hi there! As I finish up Gorf Arcade, I was looking into updating my SaveKey detection routine so that it can also determine if there is an AtariVox connected vs. just a SaveKey. I already know how to detect a SaveKey, but was was wondering how or if other programmers detect if the SaveKey is actually an AtariVox? I'm stepping through the Speakjet code through Stella to see if there is any difference (ie. carry flag set/reset if you attempt to write to the Speakjet and it's not there, etc.) between configuring a SaveKey vs. and AtariVox but figured I'd see if there is already a tried-and-true method available. Any help is greatly appreciated! Thanks, John
  6. I didn't notice this list until djpowerplayer's comment brought it up to the top … Grizzards also uses AtariVox both for saving and prattling on quite a lot. (All signposts, all NPC dialog, and combat narration, among other bits.) I've lately noticed that the allocation list got rolled back to an earlier version that omits us (messaged Albert about it) The Demo uses Scratchpad space, but the full game uses dedicated blocks.
  7. It would be nice if someone added AtariVox support for Centipede and Millipede.
  8. Yeah, but it needs to be clear for the first byte that is read only (the state it will be in after i2c_startwrite). Subsequent bytes will need overflow to be set, not clear (i2c_rxbyte sets overflow). I think this is a rare corner case that few people see, because in most cases, loading is done all at once at the beginning, and not spread out over several frames with other processing in-between. Also, it won't be an issue if you re-initialize every time you read more bytes. I wrote a small test program just to make sure what I understood about the behavior was correct, and that there was nothing different about how the normal right port driver performs compared to the left. This loads a block of data at $3000 at startup (the numbers 63 to 0 descending), then loads them into RAM two bytes per frame. It displays the contents of that block of RAM on the screen as colors. Fire button: Reload data Left Difficulty=B: Save and restore processor status to preserve the overflow flag. Left Difficulty=A: Do not restore processor status (overflow is cleared before the load function). testread.zip
  9. No, I don't think it is the left driver. Have you tried to simply clear the V-flag instead of restoring it?
  10. You are thinking that this issue is something particular to the changes made to the left driver, then? It looks like the driver sends an acknowledge bit if overflow is set when doing an i2c_rxbyte, and then sets overflow explicitly, presumably for the next byte. Maybe I can do a simple test program to read a couple of bytes each frame using only the right driver, and seeing if clearing the overflow between reads stops the reads from working as I am seeing in my utility. That would confirm or eliminate the modified left driver as a factor.
  11. Yes, the V-flag is used by the i2c include file (not that it is cleared in SetupSaveKey). But usually you do not have to care for it. Probably you have modified the code so that it becomes important.
  12. Okay, so I did decide to go back and figure this out even though I have a working utility now because I wanted to understand what was going on. TL;DR I think the issue was that you need to preserve the overflow flag if you run other code between reads without reinitializing the read everytime. I was getting indeterminate results because I was running my subsequent reads with the overflow flag in an indeterminate state after running other code. If I reinitialized the read every time I read some bytes, and ran the i2c_rxbyte calls back to back afterwards, then this wouldn't be an issue. The overflow flag being set or clear determines whether or not the code sends an acknowledge bit to the device. Now before I call the routine to continue my read, I have this code to restore the state of the overflow flag: lda ProcessorStatus pha plp And after I run my routine, I have this code to save the state of the overflow flag: php pla sta ProcessorStatus @Thomas Jentzsch @RevEng, or anyone else who is highly familiar with the savekey driver code, does my reasoning seem sound here? Here's my current source/ROM with drivers: copyvox2.zip
  13. Whelp ... I put aside trying to find the cause of this, and went ahead and finished the utility. After all of the changes I made, I can't reproduce the original problem. So ... I guess accidentally fixed by code redesign? It kind of bugs me not knowing what was going on, but perhaps not enough to spend a lot of time debugging something that works now. Anyway, here is the latest version. I'll probably make a topic in the 2600 Programming forum as well. Usage: After launching the utility, plug the source AtariVox/SaveKey into the left port, and the destination AV/SK into the right port, then press Reset. The utility will then attempt to detect the devices, and report the results. If both are detected, you can hit Reset again to begin the copy. The default mode is "No Overwrite", where the utility will not overwrite any blocks on the destination device that are not blank (all $FF value). Hitting Select before starting the copy changes the mode to "Overwrite", which will replace non-empty blocks on the destination device with the contents of the source device. In both modes, to save time and writes, blank blocks from the source device are not written to the destination device. I have tested this in Stella and on hardware successfully, but use with caution as there may still be some bugs that I haven't seen. copyvox.bin
  14. I had thought that you were sending the start address on every call to LoadSaveKey and maybe the EEPROM could get confused between the address writes. I see now on a closer read that you're only doing the address write every 64 bytes, so that's probably not a concern really. (I do do random reads more-or-less back-to-back without a wait-for-ack.) One thing that's probably completely irrelevant is that the data sheet (p.13, § 8.3) says > Following the final byte transmitted to the master [the console], the master will NOT [emph. orig.] generate an Acknowledge, but will generate a Stop condition. … but the driver code does always send an ack in your i2c_rxbyte[l] routines. My code (which is closely based on the same original) does the same thing, though, without issues. Sorry to not be more helpful. I'll have to look that up now (now that it's “too late for me” I suppose, but I am curious.)
  15. Another update. apparently my reads stop working after I run my ProgressBar sub during the visible screen. When I comment it out, everything works fine. I definitely don't see anything in there that could cause this, however, so I'll work on figuring out that part next.
  16. I'm the one who altered the driver to work on the left port (with extensive help from @Thomas Jentzsch), and I didn't update cycle counts in comments when I did so. The issue I'm having in on a read. As for writes, I do wait for the better part of a frame after doing a stopwrite before doing any other operation. Come to think of it, I shouldn't even have to do that since the writes are to the right SaveKey, and the next operation is a read from the left SaveKey. Yes, I'm reading 2 bytes per pass, but 2 times per frame: vertical blank, the unused portion of the visible screen, and overscan. I don't do an i2c_stopreadl until I'm done with the entire block, though. This was copied from @Thomas Jentzsch's code in the SaveKey for Dummies topic for the address initialization portion of the SaveKey setup.
  17. LoL. I was just about to offer to test on hardware but you beat me to it. I did see that the comments in the “left” source seem to be incorrect w.r.t. the longer procedures. eg: if I2C_TXBITL takes 30 cycles rather than 22, then i2c_startreadl is really more like 38/39 cycles. I ran into a problem when trying to do back-to-back writes, and had to inject something to wait for ACK. Looking at the offending code (around ll. 516-539) briefly it looks like you're reading two bytes per operation, (per frame, I think?) and maybe the write of the new start address on each pass is not registering because there's no wait-for-ack after the last stop reading? That seems like a real stretch, though, if that's really a whole frame apart. I'm also a little curious about the `clv` at line 517, as I don't recall ever having to do that.
  18. Update: I decided to take the plunge and run it on hardware, after all. I saw the same results as under Stella: only the first two bytes are read correctly, and the rest are read as $FF, as if I had run i2c_stopwritel prematurely. As far as I can tell, the only difference between the first two bytes read and all the others is the passage of time. Anyway, I can at least rule out Stella's AtariVox/SaveKey emulation from the left port as a cause.
  19. So - with SaveKey stuff fresh in my mind, I decided to do a clean rewrite of this utility. I seem to be having issues with the read portion from the left SaveKey. Specifically, it reads the first two bites after initializing successfully, but on subsequent calls, it reads all bytes as $FF regardless of the actual data stored at that location. The read function (ReadSaveKey) is largely identical to my working code in my recent SaveKey editor, except for the fact that it is modified to use the functions in the i2c_v2.3left.inc file. So I'm wondering if there might be any remaining issues in the i2c_v2.3left.inc file, or if it's an issue with Stella's ability to use AtariVox/SaveKey from the left port. To test in Stella (as I'm afraid of trashing my actual devices), I set the left device to AtariVox, and the right device to SaveKey since each of these uses a different data file. Does anyone have any ideas as to why the first two bytes would read correctly, but all others would return $FF? copyvox2.zip
  20. That is awesome, thank you for creating this and sharing it with the community! ..Al
  21. I can already see this as extremely useful for testing Grizzards on hardware, thank you. I've been making one-off binaries to tweak save games to test various scenarios (because replaying a couple hours of the game to get to the same glitch again is onerous) but this sort of tool is exactly what the doctor ordered!
  22. In the midst of investigating possible issues with my saved stats in my WIP Wordle clone, I thought it would be useful to have an easy way to display and edit the SaveKey data as needed. I wanted to be able to view/edit all 64 bytes in a block at once without flicker. Anyway, here's what I have come up with in case it's useful to anyone else. To use, enter the base address of the block you wish to edit, and choose "Reload Data" (it defaults to the beginning of the scratch space). Navigate the cursor with the joystick to the byte you wish to edit, and press fire. The cursor changes color, and you can change the value of the chosen byte one nybble at a time. Move the joystick up and down to change the value of the nybble, and move the joystick left or right to select the other nybble. Press fire again to exit edit mode and choose another byte, or save your changes as desired. Base Address: The beginning of the 64 byte block you are viewing/editing. Save Changes: Saves what is currently shown on the screen to the specified base address. Reload Data: Loads 64 bytes starting at the base address into memory, and displays the contents on the screen. visk.bin
  23. It would be great if the Save Key Copy Utility could work on a game by game basis with a menu (with option to copy unassigned slots as well) just in case somebody had a particular savegame/highscore on one device and wanted to copy just that one over. I have a Wall Jump Ninja record on my old AtariVox that I'd love to copy over, but not the rest of the data. I'm trying to think of a use case for 4 AtariVoxs connected all at once... a choir of robots singing? A 4.0 Quadraphonic sound demo? Hahah - James
  24. FWIW Penult uses the same allocation as Space Game. Since the latter only uses 9 bytes, I save Penult game data in the same block.
  25. The Savekey Copy utility sounds cool! In theory, you should be able to hook up 2 AV/SaveKeys, one to QT port 2 and the other to QT port 4 and enable/disable TIA dumpports to switch between each. Since they will both be recognized by the right port of the Atari, you can use the same Savekey code for each as you probably know (hooking one up to the left Atari port would require different SaveKey code that reads/writes to that port of course ). Good luck!
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...