Alternatives to battery save

Alternatives to battery save
by on (#64073)
So I want to develop an original NES game that can save the player's progress across power cycles. I brainstormed several ways to go about it:

I could design the game not to need any data saved across power cycles, but I thought I wanted to get away from single-screen puzzle games.

I could use a password system, but that can't really save more than 32 bits without being annoying. (See, for example, 48-character passwords in The Lord of the Rings for Super NES.)

I could hack up an existing SNROM cartridge. But a lot of those either are higher-value games like Dragon Warrior 2 or Final Fantasy or lack the passive components needed for a battery, and I'd have to find them in lots and pay to have them shipped to whatever replicator I end up with, and the supply of those will eventually run out.

I could make a new cartridge functionally identical to SNROM, with SRAM and a battery. I asked bunnyboy about this a few months ago, but he said he'd never done battery save before on his MMC1 ReproPak board, and it'd probably be expensive in terms of parts (board with mapper, case, CIC, PRG EPROM, two RAMs, passives, and a battery).

Around the same time, Memblers suggested using a parallel flash memory for the PRG ROM and reserving half of that for saving. But saving to flash is a read-modify-write operation, and a lot of 5V flash chips have erase blocks noticeably bigger than the 1 KiB I have available ($0400-$07FF) after subtracting the zero page, the stack, and the buffer containing the data that needs to be saved in the first place.

A bunch of GBA and DS games use 3.3V serial EEPROM. A 5V one could be shoehorned into a batteryless SNROM-clone or even a discrete board with a 4-NAND for decoding $6000-$7FFF. But a lot of data sheets for 5V serial EEPROMs state that they are "not recommended for new design".

I could have it run only in emulators and on the PowerPak. This would have the advantage of letting players trade saved games on the Internet. This would rely on PayPal donations to encourage me to continue development.

Or I could just go the Cave Story/MM9 route and develop for SDL instead.

Have you any idea which is most viable?

by on (#64075)
For completeness:

Have player leave his NES on between runs.

Have player record his items and position, and enter them directly (honor system).

Use a NVSRAM with internal battery, in a normal WRAM-supporting board.

by on (#64077)
Quote:
This would rely on PayPal donations to encourage me to continue development.

If your only motivation is cash, then you could as well stop there.

Other than that, your best bet is without a doubt to make your game MMC1 compatible. If you ever want to make cartridges of it, which would be likely only if you get to a far point in the development of your game, there sure will be a solution, and you shouldn't avoid this because "it's expensive", because distributing a ROM on the net isn't expensive. Yes the powerpak is expensive but you buy it once and don't need to buy it again. You'd be repeating the error Nintendo did when they made Metroid use 64 letters case sensitive passwords which is extremely annoying instead of battery saves.

Some Famicom games uses serial EEPROMs too you'd want to look for that. But even if make a cartridge with them - you'd have "saved" money but your thing will not be very compatible with emulators.

If you want somehting purely hardware and not emulable, the best option would be a serial memory card that plugs in controller #2 or bottom connector, and would be accessible trough $4016/7. It could handle memory for dozen of games and be reliable, like Memory Cards for Playstation consoles.

by on (#64079)
Quote:
A bunch of GBA and DS games use 3.3V serial EEPROM. A 5V one could be shoehorned into a batteryless SNROM-clone or even a discrete board with a 4-NAND for decoding $6000-$7FFF. But a lot of data sheets for 5V serial EEPROMs state that they are "not recommended for new design".


Microchip's I²C EEPROMs shouldn't be too limited life, and because of heavy investment by the automotive industry should remain 5V for a while, Also, they have a large number of 5V-compatible micros which could be programmed to pretend to be an I²C or SPI EEPROM.

Also, using a 3.3V I²C EEPROM (because it's open collector) should be as simple as adding a zener diode.

by on (#64084)
I'm not necessarily looking for cash in the short term. I'm just looking for something that will keep me from defecting to the PC or another more general, more CV-relevant platform like Android or XNA. I have a feeling that a completed commercial product on my CV will open more doors once I do join the video game industry; see a previous topic about this.

Another possibility: Use a flash memory that allows reprogramming in smaller units than erasing (e.g. 16 KiB erase, 1 KiB program). Report capacity to the user based on two or three blocks less capacity than the memory actually has. Once only one empty block remains, "defragment" the memory by finding the erase block with the most entries that have been marked as deleted, copying that to the free block, and finally erasing the source block.

by on (#64087)
I think it depends on the type of game you're making. The design of it makes a huge impact on what to pick.

If progress is more linear (i.e. one level after another, certain items are required to beat a level, therefore if you've beaten the level, you have said items) you're probably fine just with a password system.

I guess I'm more of a 'If you build it, they will come' type of guy, though.

by on (#64088)
I assume you mean 32 bytes, as it should be pretty trivial to cram 32 bits into a 6-7 character password.

Metroid and Castlevania 2 cram about 200 bits into theirs I think, maybe a bit more.

by on (#64093)
ReaperSMS wrote:
I assume you mean 32 bytes, as it should be pretty trivial to cram 32 bits into a 6-7 character password.

A password with 8 characters might carry 32 payload bits and 8 error detection bits:
Code:
p 4 $ $ w 0 r d
^
0 1 2 3 4 5 6 7
8 9 b c d f g h  <- 5 bits per character
j k L m n p q r
$ t v w x y z -

It's good for a game about as complex as Mega Man series (8 levels doable out of order, 16 pickups) or even a fairly railroaded action RPG with a 1-character party (8-bit sqrt(cash), 8-bit sqrt(experience), 4-bit weapon, 4-bit chapter, 8 subgoals per chapter). But a password much longer than that, like the one in Metroid (NES) or LOTR (SNES) or the old save bonus of Golden Sun (GBA), isn't so practical to use after every play session, and it'd be impossible to save the state of something like Harvest Moon or Videomation in a password.

The "honor system" that blargg mentions is equivalent to a long password.

by on (#64096)
tepples wrote:
Another possibility: Use a flash memory that allows reprogramming in smaller units than erasing (e.g. 16 KiB erase, 1 KiB program).


With the 29F family chips, I've never seen any require programming more than a single byte at once. I used that aspect of it on the NSF loading routine for Squeedo, I left some key addresses in the program as $FFFF, to be filled out later when the right value was known. It appeared that writing $FF when it's blank is the same as leaving it blank.

I'm not sure what flash chip to recommend, I haven't looked around at what's available now and I don't know what size you would need, either. I still have a bunch of 29F040s if that would be usable (512kB / 64kB erase sectors).

by on (#64109)
A 29F010 or 29F040 might work. The program would occupy half of the eight sectors, and the rest would rotate among these functions:
  1. User data
  2. More user data
  3. Revisions to user data, as they are written
  4. Area that will get erased and filled with a copy of sector a, b, or c, whichever has most deleted revisions

The user would see only enough capacity to fill two of these four sectors.

But a mapper designed for use with a 29F040 would need either a fixed bank at $E000-$FFFF or a good reset detector to reset the program bank so that a CPU reset never starts the program counter in a freshly erased sector.

by on (#64115)
Isn't it dangerous to put the program and the saves in the same chip? I mean, couldn't a crash or bad connection accidentally cause parts of the program to be overwritten? A corrupted save is already bad enough, but a corrupted program is much worse! Is there a way to prevent against that?

by on (#64116)
I may feel harsh but making a nes game is maybe not the right way to "get into the industry" with the current climate of off sourcing jobs to India and China.

If your goal is to be a programmer and not a designer, you need skill that be used now. But I guess we all have the right to dream, myself included ;)

by on (#64118)
tepples: A reset detector shouldn't be needed, we can use pull-up resistors either on the memory chip or on the logic inputs so there's a known state immediately. But you will want a little reset vector code in the data banks (if there isn't a fixed one, in case the user resets while it's in there). Doing something like UNROM might not be too bad, if 32kB banks are a problem.

tokumaru: There is a fairly lengthy unlock command before an erase command can be given, and the same thing for programming, so it should never happen randomly. If there's some kind of intermittent connection that would be bad news, but it would take a miracle for it to not crash and also send a valid command to the wrong bank.

by on (#64656)
I just finished a demo of password generation, entry, and validation.

The NVSRAM that blargg mentioned is $7.50 each, compared to $2.50 each for an ordinary 62256.

The method of splitting a 29F040 between game and save would appear to need a custom mapper that places its registers below $6000 so as to distinguish flash writes from mapper writes.

On #nesdev, someone suggested Ramtron FRAM. But parallel FRAMs are considered obsolete according to Ramtron's web site, and I²C FRAMs appear to need mapper support (even if only an open-collector latch so that the CPU can bit-bang it).


EDIT (2017): Mirrored as an attachment

by on (#64673)
What are you really hoping for? Something that's compatible with the current NES save conventions (i.e. some kind of NVRAM memory-mapped in $6000-$7fff) or a cart with a cheaper way of holding the save data? Because you seem to be getting stuck on wanting both.

Regardless: Microchip and Atmel both say they'll be making 5V compatible SPI EEPROMs for the foreseeable future.

by on (#64675)
tepples wrote:
The method of splitting a 29F040 between game and save would appear to need a custom mapper that places its registers below $6000 so as to distinguish flash writes from mapper writes.


It can be done with a 74HC139, which can be bought for maybe 10 cents, that chip could supply a chip enable for both a mapper register and WRAM. A generic 62256 SRAM cost should be around $1. You also want to consider assembly cost at around $.02 per IC pin (nevermind setup cost).

Next step up from the 10-cent mapper is the $1 mapper, a small CPLD. I've been wanting to make a small one in Verilog before I make the larger one later (heheh), I just haven't needed to yet.

For any kinds of parts cost I estimate that (in the worse case) something will add 3 times it's value to the selling price. Then try to figure out if it's worth it, if it adds that much value to it.

by on (#64676)
Funny idea for a password (or pass sentence rather) system would be where it uses words instead of characters for the password. So let's say the dictionary contains 256 different words so each word represents a byte. The password would be something like "retrain museum hoe domed".

Easy to write down, easier to comprehend than bunch of random characters, but the dictionary takes space in ROM and entering the password is kind of PITA. The input screen could use some kind of word prediction though similar to ones used in mobile phones.

by on (#64714)
lidnariq wrote:
What are you really hoping for? Something that's compatible with the current NES save conventions (i.e. some kind of NVRAM memory-mapped in $6000-$7fff) or a cart with a cheaper way of holding the save data? Because you seem to be getting stuck on wanting both.

It'd be nice to have something I can use in an emulator or on a PowerPak so that I can test the saving code. But I guess I ought to complete the SNROM+battery version of one of these projects first so that we have something to port.

by on (#65526)
I want the extra work RAM even if it isn't battery-backed, but I also want the save. That's why I suggested that something had to be mapped into $5000-$5FFF, whether it is the control register for an I2C port (for serial FRAM) or a control for write-enabling the PRG ROM (for using a 29F040 as the PRG ROM and saving back to half of that). BootGod's DB lists six Japan-only games by Bandai on mapper 16 that use an I2C-like serial EEPROM.

by on (#65554)
I looked up digikey pricing on Microchip EEPROMs on digikey on some sizes and it seems to roughly like this (obviously not a complete list):

$0.20 256 bytes
$0.40 8kB
$3.14 128kB (largest available)

I just wonder if there is a good way to get a clock for it. The trouble I see is that most address decoding will involve PRG/CE, which is already gated with M2 (the clock). Not sure if that's a problem yet (obviously it's been done before). There's probably one with an enable, I didn't check.

by on (#65586)
This has been really interesting to consider all the possible configurations. After talking to kevtris today about how to interface an I2C EEPROM to NES (not too bad, but the cart requires 2 latched bits in, and 1 latched bit out to the NES. There probably is a cheap 1-bit latch, I haven't looked it up. But that should be trivial with a CPLD, and would tie right in with the rest of the mapper.

But kevtris and I both agreed that it's pretty cheap to add a battery. I think parts cost for CR2032 + SMT battery holder could be about 60 cents. So if the WRAM is already there, it's a decent option.

EEPROM is attractive for being maintenance-free. The batteries should be good for years at a time without an NV-controller, but I think it's dependent on the leakage current of the particular SRAM. Zelda lasted a long time (almost 20 years for my copy I think), but I imagine Nintendo was as selective as possible about the particular parts used. If the save-data continuity matters that much to the user, they probably want a CopyNES or a transfer cable anyways.

by on (#65590)
Memblers wrote:
$0.20 256 bytes
$0.40 8kB
$3.14 128kB (largest available)


What quantities are you talking about, here? Microchip themselves gives quotes of 17c/29c/$2.40 for the those parts in quantities of 1k.

Quote:
how to interface an I2C EEPROM to NES (not too bad, but the cart requires 2 latched bits in, and 1 latched bit out to the NES.


A SPI interface should only require one latch -- or could be attached to the joypad port. (Whether that's desirable is another question.)

by on (#65596)
I think those prices were for 100 quantity, I could have mixed them up.

Quote:
A SPI interface should only require one latch -- or could be attached to the joypad port. (Whether that's desirable is another question.)


I haven't looked at the speeds yet, but the latched clock and data might be needed if the NES is faster than the chip is rated for.

by on (#65606)
A lot of these I2C parts are rated for 1.0 MHz. The NES is up to 1.8, but it'd probably actually operate it at 1/6 of that (ROL/STA loop). The CPLD could handle clocking the interface, but then someone who knows Verilog and soldering would need to handle that.

I understand CPLDs are sized by how many bits of state they store and how many I/O pins they have. How much effort would it take to write a CPLD mapper in Verilog that does this:
  • PRG switching equivalent to MMC1 SUROM (4 bits for PRG page number, 1 bit for 256 KiB super-bank number, 2 bits for PRG bank mode)
  • One switchable CHR bank at $1C00, out of 32, so that 1 KB of a 62256 CHR RAM page can be bankswitched (5 bits)
  • Mirroring like MMC1 (2 bits)
  • A latch used for I2C communication (3 bits)
  • Reset detection (? bits)
  • All registers in $5000-$500F space so as not to overlap if used in write-back-to-29F040 mode
And about 34 I/O pins:
  • NES side: PRG A14-A12, A3-A0, D3-D0, /CE, R/W, M2; CHR A13-A10; CIRAM A10 (21 pins)
  • Internal side: PRG ROM A18-A14, /CE; WRAM /CE; CHR RAM A14-A11 out (A10 shared with CIRAM); I2C SDA, SCL (13 pins)

For 7 more pins and 2 more bits, you could add an IRQ on tile $FF access, but let's not get ahead of ourselves because the goal of this topic is to explore a new mapper allowing easy ports from SNROM and SUROM (MMC1 + PRG RAM + CHR RAM) but supporting flash-writeback and I2C save types.

by on (#65768)
The description helped me get started on it, thanks.

So far it has pretty much been simple to implement. This is my first practical verilog project, so most of the effort was learning the language (conclusion - extremely C-like in syntax, not bad at all).

So far it's using 30 macrocells (out of 36 in this smallest CPLD). It's not tested at all, but it does compile and synthesize.

What I've come up with so far is:
-PRG $8000 and $C000 are banked independently (so it supersedes any 16kb and 32kB modes). 256kB max though.
-CHR-RAM Is banked, 2 banks again, at $0800-$0FFF and $1800-$1FFF, the rest is fixed.
-registers at $5000-$5007
-WRAM is banked

Also PRG /CE (to the ROM) isn't needed, but PRG /RD is. Since the NES provides no active-low read signal, which is no problem for SRAM, but I don't know if I trust using /CE as /RD with any random type of flashrom. Might be OK on specific ones. I suppose that could be a minor problem for the MMC1 flash cart idea in the other thread. On Squeedo I just invert the PRG R/W line using a NAND gate, making it low on read to get this signal.

i2c remains to be added. Should be easy.

I'm also wondering if it's worth using the on-board RAM for nametables. Allowing nametable banking, and 4-screen mode. I'll look into that last (and hopefully have enough I/Os to make it optional, probably not though).

It definitely needs a bit more size with the PRG-ROM bankswitching, so the 'super-bank' idea sounds effective. I think I could also double the size with no more I/Os by doing a trick where $8000 could only use even banks, and $C000 can only use odd banks. It makes sense to me, it doubles the maximum size but also forces you to use both banks evenly (so it might take a bit of duplicate code).

by on (#65770)
Thanks for starting on this, Memblers.

Memblers wrote:
I'm also wondering if it's worth using the on-board RAM for nametables.

MMC1 style mirroring needs 2 bits of state, which means about 2 macrocells. A 4-screen mode fixed to the last 4 KiB of CHR RAM would take one more bit. Independent switching might exceed 36 macrocells.

Quote:
It definitely needs a bit more size with the PRG-ROM bankswitching, so the 'super-bank' idea sounds effective.

But we'd still have to add some sort of reset detector to make it always start in one or the other super-bank, so that we don't power on or reset into a freshly erased sector of a 29F040 chip. Is this there, or are you relying on a 16-byte reset stub in all banks?

Further steps:
  1. Test it
  2. Make I2C
  3. Make a demo of saving on both I2C and flash save types
  4. Port it to PowerPak's FPGA
  5. Get it working in at least one PC-based emulator

If you get this working, I'm willing to give you some repro business by developing a game for it.

by on (#65772)
Actually I'm still kinda concerned about the power-on state of the CPLD. It has to copy the config out of EEPROM into SRAM, but it gets an early start by doing this while the VCC voltage is still rising. But I also have to regulate 3V to give the CPLD, which will add some kind of delay (not sure what).

So I'm thinking either:
a) it will be fine and start up in a good state
b) I could tri-state the latch outputs and add pull-up resistors
c) something else?

I'm really not sure what will happen at startup, if the NES can possibly come alive first, or what.

by on (#65815)
Double posting, but the story continues..

CPLD start-up should be safe, due to the NES CPU reset having a delay. But since reset is done by the lockout chip and by charging a capacitor, how different is a toploader and famicom? I don't know. But definitely they should have delays built in, as I realize now it would be stupid anyways if the CPU started as soon as possible (possibly before the memory is ready, etc).

I've got the reset detector figured out, it's as simple as using a capacitor charged by the M2 clock to release it from reset mode. Though I'm getting kind of stingy with the I/Os at this point (I think the reset could share an I/O with part of the i2c if it has to, as I don't think one wouldn't ever need both at the same time).

by on (#66020)
Triple post c-c-combo!

It all fits in the CPLD, using 36 macrocells and 34 I/Os. I'll see about making a PowerPak version of it (I'm still waiting on the Xilinx ise 9.1 download which is 2.5GB).

So that fills up the chip. Reset is in there, it resets the PRG banking latches only, but I guess with the added diode/cap/resistor circuit it would reset the banking even if the reset button is hit. Some pirate multi-carts use the same circuit. I think it might not be needed for power-on, because in the design software you apparently can specify a start-up state for all of the registers. So hopefully this pin and extra circuit isn't even needed.

The "superbank" bit is in there, so it can address 512kB. That's perfect for 32-pin memories.

I2C support is in, both the address and data line are bidirectional, latched I/Os for the NES to control.

I looked around at flash memories available, and the SST39SF family seems to be nice and very cheap. It is byte-programmable and uses 4kB-sized erase sectors, so I think this makes the I2C / EPROM combination a lot less appealing. It claims 10k erase cycles minimum, but that could be extended further with some wear-leveling.

If I took I2C out of the design, that would free up a couple pins. Perhaps I could even make the PRG bankswitching 5-bits for both slots instead of 4 (so the superbank bit would no longer be needed).


edit - For the SST chip I noticed the flash write endurance is 100k in another datasheet. I think maybe the 512kB sized one is 10k. The price difference between the sizes is negligible.

by on (#66027)
tepples wrote:
I just finished a demo of password generation, entry, and validation.
Your method looks similar to what I'd have done if I were to code a password system.

May I ask how you encrypt the bits ? It's not clear in the doccumentation. It says it's inspired by TEA, but where can I find info about that ?

If I were to do that I'll scrable the bits in a random order and EOR them with some constant to make it impossible to "guess" their order originally. Is it what you're doing ?

So I guess the minimal lenght of a password of a 32 caracter set is (8/5)*(#of bytes + 1)
Your case is for a # of bytes of 7 (since there is one validation byte).

Also I wonder if it's possible to make the validation byte so that the "best" possible password has a meaning in english (or whatever language), but without "hard-coding" it. I've heard DQ1 and/or 2 does something like that in japanese, but because they're in japanese it's hard to verify.

Finally, I think another system should be good, and that doesn't require the character set to be exactly 32 chars : You make a big number from your game variables (bit-scrambled of course) and "convert" this number into base 26 (for example, assuming you use the 26 latin letters).
To decode the password, convert it back to base 2 and de-scramble the bits, with of course some validation bits that should remain constant.
The base conversion itself acts like encription, so I guess it should be hard to "guess" passwords.
It's however more complicated to compute the # of symbols per bits.

by on (#66035)
Bregalad wrote:
tepples wrote:
I just finished a demo of password generation, entry, and validation.
Your method looks similar to what I'd have done if I were to code a password system.

May I ask how you encrypt the bits ? It's not clear in the doccumentation.

Before I implemented it in assembly language, I prototyped it in C so that I could make sure my logic was correct. This is tools/pw.c.

Quote:
It says it's inspired by TEA, but where can I find info about that ?

http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm

Like TEA, this cipher derives its diffusion from shifting two other bytes left and right and derives its nonlinearity from mixing xor and add operations.

Quote:
If I were to do that I'll scrable the bits in a random order and EOR them with some constant to make it impossible to "guess" their order originally. Is it what you're doing ?

Sort of. Most modern ciphers use a Feistel network so that every bit can affect every other bit in hard-to-predict ways. Yes, it finishes in one frame.

Quote:
So I guess the minimal lenght of a password of a 32 caracter set is (8/5)*(#of bytes + 1)
Your case is for a # of bytes of 7 (since there is one validation byte).

There are 32 bits; 8 of them are for validation. Using more than one character defeats "I'll try a random cuss word with every single possible character after it". It has only 1/8 chance of working.

by on (#66038)
Quote:
There are 32 bits; 8 of them are for validation.

I guess you mean 32 bit + 8 for validation (what I said before was wrong too anyway). So there is 32 actual bits, or 4 bytes. My formula gives : 8/5 * (4 + 1) = 8 chars.

In theory you could make any very complex RPG use passwords, but all it comes to the length of it. For example an RPG which would require 2kb to save would make a 3'277 letter password, even worse than those Golden Sun passwords.

Thank you for the link. Well it looks like your system works very well I tried to input random stuff and I never hapened to find any valid password. If I understand well, 1/256 of possible passwords are valid (those who gives that 0x2A byte at the end after being decoded). I guess that's a good balance between increasing the password length and increasing the chances of a user making up a valid password by luck.
You'd also want to make sure no valid password is made of only one character repeated or something close to it (remember that Kid Icarus password : uuuuuuuuu8 ??).
It looks like none of single-letter password is valid in your demo, but I wonder if a single letter + a different letter exists (there is far too many possibilities for me to try all of them - so even if one exists it's not an issue).

Quote:
Yes, it finishes in one frame.

Not that this really matters (as long as your sound engine is in a separate NMI thread), it's not like any game were generating passwords every frame. However, if the encryption algorithm is so complex it needs extra RAM, you might as well attach a battery to it / set the battery bit in iNES header.

by on (#66047)
Sorry to double-post, but I just don't understand a single bit of the wikipedia page you linked. The french version is completely lacking so it's not of any help either.

Also I managed to enter a valid password by luck. It's : 11289LNK
I had to do this for some time before it happened, but it happened.

by on (#66062)
Bregalad wrote:
Sorry to double-post, but I just don't understand a single bit of the wikipedia page you linked.

Did you understand not one bit of any of the three Wikipedia pages? If so, then you're probably brand new to cryptography. Does the Block cipher article help any? Yes, the French version of this article still appears to be what English Wikipedia calls a "stub", as is the article about TEA itself, but Or does this French article about a TEA variant and its English counterpart appear more complete.

by on (#66084)
Regarding saves, one could use a 5V flash chip and just divide it into small blocks and successively fill them, once all are filled you erase the chip and start over. You'd be using the last saved block every time when loading... this helps with extending the life of the flash, plus you got backup saves ^^
You can program individual bytes on a typical NOR flash, but erase is in blocks or whole chip at once. You can program ones to zero but not the other way.

by on (#66085)
Quote:
If so, then you're probably brand new to cryptography.

I am indeed.
What I figured is that if I just scramble and XOR the bits like I suggested, if only one bit is changed in the memory, only one bit will change in the password, and this can be easily "attacked". For this reason your complex method sounds better.

Anyway, all it takes is to do any reversible opperation on the bits. This include :
- Changing bits order (shifting left and right with the bits that goes to the left fall on the right and vice-versa goes into this cathegory). Reverse operation : Change the bits so they are like they were before (or shift in the opposite direction)
- Add a constant to the word or a part of it (reverse opperation : add the constant's two's complement, relying on overflow/underflow of course)
- XOR with a constant (reverse operation of itself)

Maybe (likely) there are other reversible opperations I missed but in any cases after a decently long chain of the opperations I listed, it should be enough crypted so that it takes some effort to reverse enginner (and after all this is very fun stuff ! Letting no chance to the reverse engineer is not fair).

To have a selectable "ultimate password" that have a meaning in an human language such as english you should add a final XOR at the end of the chain of operations so that it gets you the desired password. Or do it the lazy way and hard-code it.