Jump to content
IGNORED

SaveKey for Dummies!


Recommended Posts

  • 6 months later...

I noticed that reading the SaveKey right after startup sometimes fails for me (in about 1 out of 10 cases). Maybe it is a problem of my SaveKey, I'm not sure.

Anyway, by waiting a few milliseconds after startup (~80 scan lines), these problems went away.

Edited by Dionoid
Link to comment
Share on other sites

  • 10 months later...
On 3/6/2016 at 9:25 AM, Thomas Jentzsch said:

Hi,
I found no easy to use code for loading and storing on a SaveKey or AtariVox. Therefore I am presenting my code here.

All it takes are:

  • add the attached include file to your code's directory
  • define the three variables/constants at the beginning of the code
  • call WriteSaveKey for storing your score etc.
  • call ReadSaveKey for reading what you have stored

Notes:

  • if you have multiple scores to store (e.g. different game modes), you have to modify the address used in SetupSaveKey.
  • the X register is not used in any i2c subroutine.
  • after calling WriteSaveKey you must wait at least 5ms (~80 scan lines) before accessing the SaveKey again.
  • update i2c v2.3 attached, fixes unwanted noise issues when using an AtariVox

skBuffer    = <score RAM>       ; define the RAM address you want to store
SK_BYTES    = <n>               ; define how many bytes your want to store
SAVEKEY_ADR = $xxxx             ; ask Albert for a free slot! 
 
    include "i2c_v2.3.inc"      ; a highly optimized (for space) version   
    i2c_subs                    ; this makes the i2c macros of the include file known to the code 

;-------------------------------------------------------------------------------
WriteSaveKey SUBROUTINE         ; total cycles = 1923 (for 3 bytes)
;-------------------------------------------------------------------------------
; setup SaveKey:
    jsr     SetupSaveKey        ; 6+927
    bcc     .noSKfound          ; 2/3

; write high score:
    ldx     #SK_BYTES-1         ; 2 = 937   
.loopWriteSK
    lda     skBuffer,x          ; 4
    jsr     i2c_txbyte          ;6+296      transmit to EEPROM
    dex                         ; 2
    bpl     .loopWriteSK        ; 2/3=932

; stop write:
    jsr     i2c_stopwrite       ; 6+42=48   terminate write and commit to memory
.noSKfound
    rts                         ; 6

;-------------------------------------------------------------------------------
ReadSaveKey SUBROUTINE          ; total cycles = 2440 (for 3 bytes)
;-------------------------------------------------------------------------------
; setup SaveKey:
    jsr     SetupSaveKey        ;6+927
    bcc     .noSKfound          ; 2/3

; start read:
    jsr     i2c_stopwrite       ;6+42       end of "fake" write
    jsr     i2c_startread       ;6+284      Start signal and $a1 command byte

; read high score:
    ldx     #SK_BYTES-1         ; 2 = 1275
.loopReadSK
    jsr     i2c_rxbyte          ;6+333      read byte from EEPROM
    cmp     #$ff                ; 2         EEPROM slot empty? (we are assuming $ff for uninitialized space)
    bne     .skipEmptySK        ; 2/3        no, skip clear
    lda     #0                  ; 2         clear EEPROM slot
.skipEmptySK
    sta     skBuffer,x          ; 4
    dex                         ; 2
    bpl     .loopReadSK         ; 2/3=1061

; stop read:
    jsr     i2c_stopread        ;6+92=98    terminate read
.noSKfound
    rts                         ; 6

;------------------------------------------------------------------------------
SetupSaveKey SUBROUTINE         ; = 927
;------------------------------------------------------------------------------
; detect SaveKey:
    jsr     i2c_startwrite      ;6+312
    bne     .exitSK             ; 2/3

; setup address:
    clv                         ; 2
    lda     #>SAVEKEY_ADR       ; 2         upper byte of address
    jsr     i2c_txbyte          ;6+296
    lda     #<SAVEKEY_ADR       ; 2         lower byte offset
    jmp     i2c_txbyte          ;3+296      returns C==1

.exitSK
    clc
    rts

; 176 bytes in total (less if you inline the subroutines)

I hope this answers all questions. Else let me know. icon_smile.gif

SaveKey & AtariVox memory allocation list

i2c_v2.2.inc 5.18 kB · 253 downloads

i2c_v2.3.inc 5.35 kB · 247 downloads

Hello, do you have example program using this in bB please?

 

How do I actually call the methods?

Do I do something like WriteSaveKey $3001 = s? S being the variable? Thank you

Link to comment
Share on other sites

  • 3 years later...

Hello!

 

I know this is an Atari 2600-specific thread, but I wanted to bring something up that's 7800-specific which may also benefit this same code base and Thread.

 

Apparently, there is an Atari 7800 specific version of these SaveKey include files.  Here's a post that mentions it:

Would it be worth it to try to incorporate these changes into the 2600 one from this Thread?  That would make this "SaveKey for Dummies" more portable.  I'm not suggesting auto-detect code or anything as that will eat up more ROM and cycles (unless it was deemed worth it), but maybe there could be an "IF 7800" flag to differentiate.

 

This would also ensure that any bugfixes from one fork would be carried to the other line.  I'm unsure what the difficulty would be, though.

 

Link to comment
Share on other sites

That might work. But I suppose @RevEng would have to be incorporated, because he know his changes (I think I could find out) and I suppose he is able to test results. 

 

From looking at the code, he only added some NOPs (and some debug color output) to the original I2C. Probably that would work here too, but my I2C code is optimized, so one has to be careful with the changes.

Link to comment
Share on other sites

I don't personally want to take on the support for it, but If someone wants to unify both consoles in one i2c driver, go for it.

Absolutely the 7800 version just adds a few nops to enhance reliability at 7800 clock speeds. The bigger deal about unifying it is testing out any changes on both consoles, or at least advising that any given update in the unified driver hasn't been tested on one of the consoles.

  • Thanks 1
Link to comment
Share on other sites

We would have to share the work. 7800 for you and 2600 for me. 

 

The question ist, what would be the benefit? Both codes are tested and working unchanged for long time. And I don't expect any changes to come. 

Edited by Thomas Jentzsch
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Well, I had 3 reasons to bring up the idea:

 

1) I can't get the 7800 version to compile on dasm.

 

I get weird errors like this:

 

...
char = '{' 123 (-1: 0)
char = '}' 125 (-1: 49)
src/main.asm (381): error: Not enough args passed to Macro.
src/main.asm (381): error: Illegal character '{1}'.
...

 

I'm using version 2.20.14.1, which I believe is still the latest according to the github link I was using.

All I'm really doing is swapping my "include file":

 

The following fails for me:

 

        include "hdr/savekey/i2c7800.inc"

 

But the following works.


        include "hdr/savekey/i2c_v2.3.inc"

 

I'm invoking `i2c_subs` further in the file, and that's what I believe causes the failure to compile.

 

2) I noticed that the Atari 2600 version was last fixed on November 2, 2016, but the 7800 version is listed as being last updated in 2015.  So, that implies that the 7800 code probably still is missing the 2016 fix (I'm not sure).  The other alternative was to suggest porting the 7800 support to the 2600 version, so that there could be one source of truth.

 

3) This Thread is one of the top results on atariage when searching for savekey integration assistance.  Atari 7800 developers who end up here may not realize that while the implementation in this Thread will compile fine for their 7800 efforts, it may have reliability issues due to timing differences.  It's not 1:1.

 

 

It seemed like it was worth at least bringing up the idea to see if cross-pollination made any sense.  From my side of things, my goal is a bit simpler; I just want to figure out how to compile SaveKey code with the appropriate 7800 timing for a project I'm working on, but it would also be nice to have the latest fixes from both projects included if there are any.

Link to comment
Share on other sites

14 minutes ago, Propane13 said:

1) I can't get the 7800 version to compile on dasm.

...

I suppose that's a carriage return/linefeed issue. Format the file according to your OS.

14 minutes ago, Propane13 said:

2) I noticed that the Atari 2600 version was last fixed on November 2, 2016, but the 7800 version is listed as being last updated in 2015.  So, that implies that the 7800 code probably still is missing the 2016 fix (I'm not sure).  The other alternative was to suggest porting the 7800 support to the 2600 version, so that there could be one source of truth.

The fix was required due to my optimizing. Probably the 7800 code does not need it.

14 minutes ago, Propane13 said:

3) This Thread is one of the top resuls on atariage when searching for savekey integration assistance.  Atari 7800 developers who end up here may not realize that while the implementation in this Thread will compile fine for their 7800 efforts, it may have reliability issues due to timing differences.  It's not 1:1.

Well, now we have a link in here. :) And I can add a comment to my 1st post and put the link there too.

Edited by Thomas Jentzsch
  • Thanks 1
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...