The following information is pertaining to Estpolis Denki aka エストポリス伝記 aka Lufia & The Fortress of Doom.

SRAM

SRAM Checksum Algorithm

To calculate the checksum for each save slot, you start with the first offset in your save slot, and add up the little endian 16-bit numbers.

So, say for SLOT00, your first 16 bytes looked like this:

46 69 6C 65 30 30 E8 63 01 04 E5 E5 E5 E5 E5 E5

So, your first four bytes: "46 69 6c 65", are the HEX equivalent of the word "File" (if you don't believe me, look up the ASCII character table, and find that hex values 0x41 - 0x5A are upper case characters and hex 0x61 - 0x7A are lower case characters of the alphabet (A-Z and a-z respectively)).

Then, your next two bytes: "30 30", are the HEX equivalent of the printable ASCII characters 00 (the ASCII table defines hex values 0x30 - 0x39 as the textual representations of the characters 0 - 9).

Now we come to the little endian checksum part, which can be complicated, so please bear with me:

Then, the next two bytes are what your checksum is currently calculated as. Since it is a 16 byte value, to get your checksum as a decimal number, you take the first number, "0xE8", and convert it to a decimal -- 232. Now, you take the second number, "0x63", and convert it to a decimal -- 99.

But! Before you can add these two numbers together, you have multiply 99 by 256, since the number that exists there would actually be 0x6300. Anyway, 99 times 256 is 25344. Then you add 232 to that, and you get: 25576. That is your checksum value.

Why did I show you that complicated method? Because, we're dealing with little endian encoding. That means that "0x63" is your high order byte, and "0xE8" is your low order byte. The 16 bit value that is your checksum is not 0xE863, but it is actually 0x63E8. This little tidbit of information becomes important when we start going through the save slot to compute the checksum.

Now, if we were to start computing the checksum for this save slot, we would begin after the checksum bytes with the first "0x01". This is the low order byte, so the decimal equivalent here is 1. Now, we take the high order byte, which is "0x04". Remember, this is just like saying "0x0400" for the purposes of computing a checksum. So, convert the byte to a decimal -- in this case, 4, and then multiply it by 256 -- 1024; before adding back in 1. So, your first value in your checksum is 1025. You will continue in this manner until you reach the end of that save slot.

Except, there is a caveat: what happens when your checksum value goes over 0xFFFF (the biggest 16-bit number, aka. 65535). Well, your counter technically rolls back over to 0, and starts counting up again -- and you just throw away the extra.

So you've added up your save slot and you find out that it still doesn't match the two bytes at the end of "File00"? Well, that's why the assembler code up above was important -- it not only told us how the checksum algorithm works, but it also told us the base value to begin the checksum calculation off of. In this case, it is 6502. You can either start with this value from the onset, or you can add it on as the last step in the process, but regardless, the value this yields will be the two bytes that get stored away as your checksum for this save slot. Then you just have to rinse and repeat this process for the next two save slots! (by the way, 6502 is a decimal value -- not in hex).

$00/9429 A0 FC 03    LDY #$03FC              A:0070 X:616E Y:0000 ; load Y immediate with value 0x03FC
$00/942C A6 1F       LDX $1F    [$00:001F]   A:0070 X:616E Y:03FC ; load X with value at address 0x1F
$00/942E A9 02 65    LDA #$6502              A:0070 X:0000 Y:03FC ; load Accumulator with 0x6502
$00/9431 18          CLC                     A:6502 X:0000 Y:03FC ; clear the carry flag
$00/9432 7D 08 00    ADC $0008,x[$70:0008]   A:6502 X:0000 Y:03FC ; add with carry starting at address 0x0008
$00/9435 E8          INX                     A:4AE7 X:0000 Y:03FC ; increment the X register
$00/9436 E8          INX                     A:4AE7 X:0001 Y:03FC ; increment the X register (again)
$00/9437 88          DEY                     A:4AE7 X:0002 Y:03FC ; decrement the Y register
$00/9438 D0 F7       BNE $F7    [$9431]      A:4AE7 X:0002 Y:03FB ; repeat until Y hits 0 (branch not equal)
$00/943A AA          TAX                     A:592C X:07F8 Y:0000 ; transfer the accumulator into X
$00/943B 7A          PLY                     A:592C X:592C Y:0000 ; pull the Y register off of the stack
$00/943C AB          PLB                     A:592C X:592C Y:0000 ; pulls a byte off of stack into data bank
$00/943D 28          PLP                     A:592C X:592C Y:0000 ; pull processor status off of the stack
$00/943E 60          RTS                     A:592C X:592C Y:0000 ; return from subroutine

Below is a C++ program that accurately handles the checksum algorithm described above:

// File name: main.cpp
// Author: Vegetaman
// Date: February 24, 2011
// Purpose: Lufia Checksum

#include <iostream>
#include <fstream>

#define SIZE_OF_SRAM 0x2000                     // SRAM is 8K large
#define LUFIA_SRAM_FILE "C:\\Lufia.srm"         // SRAM file location
#define HALF_OF_2K 0x03FC                       // half of 2048 - 8
#define FILE00_OFFSET 0x0008                    // 8 bytes in
#define FILE01_OFFSET 0x0808                    // 2K + 8 bytes in
#define FILE02_OFFSET 0x1008                    // 4K + 8 bytes in
#define COUNTER_ROLLOVER_VALUE 0xFFFF           // max 16-bit value

using namespace std;

int main(int argc, char *argv[]){
  FILE *filePtr;                           // file pointer
  unsigned char ArrayOfSRAM[SIZE_OF_SRAM]; // array of char or bytes
  unsigned short accumulator;              // is a 16-bit unsigned integer
  unsigned short register_x;               // will be just like the register X
  unsigned short register_y;               // will be just like the register Y
  filePtr = fopen(LUFIA_SRAM_FILE, "r");   // open file Lufia.srm -- read only

  // NOTE: I am reading the SRAM into an array so I don't have to do all of my
  //       operations from the file, which would be really slow and wasteful...

  fread(ArrayOfSRAM, sizeof(char), SIZE_OF_SRAM, filePtr); // load the array
  fclose(filePtr); // always close your file handle

  // begin the routine of calculating the first 16-bit little endian checksum
  register_x = FILE00_OFFSET; // load the first offset into register X
  register_y = HALF_OF_2K;    // load 0x03FC into register Y
  accumulator = 0x6502;       // load the accumulator with the base value 6502

  while(register_y != 0){     // while Y does not equal 0 (will run 1020 times)
    accumulator += ArrayOfSRAM[register_x];      // get the first/low byte
    register_x++;                                // increment X
    accumulator += ArrayOfSRAM[register_x] << 8; // get the second/high byte
    register_x++;                                // increment X
    accumulator &= 0xFFFF;                       // discarding the carry flag
    register_y--;                                // decrement Y
  }

  // some code to throw the checksum up on the console so that it can be seen
  cout << "Checksum for FILE00: " << dec << accumulator << endl;
  cout << "Little Endian HEX: " << hex << (accumulator & 0xFF) << " ";
  cout << hex << ((accumulator >> 8) & 0xFF) << endl << endl;

  // prepare to calculate the second little endian 16-bit checksum
  register_x = FILE01_OFFSET; // load the first offset into register X
  register_y = HALF_OF_2K;    // load 0x03FC into register Y
  accumulator = 0x6502;       // load the accumulator with the base value 6502

  while(register_y != 0){     // while Y does not equal 0 (will run 1020 times)
    accumulator += ArrayOfSRAM[register_x];      // get the first/low byte
    register_x++;                                // increment X
    accumulator += ArrayOfSRAM[register_x] << 8; // get the second/high byte
    register_x++;                                // increment X
    accumulator &= 0xFFFF;                       // discarding the carry flag
    register_y--;                                // decrement Y
  }

  // some code to throw the checksum up on the console so that it can be seen
  cout << "Checksum for FILE01: " << dec << accumulator << endl;
  cout << "Little Endian HEX: " << hex << (accumulator & 0xFF) << " ";
  cout << hex << ((accumulator >> 8) & 0xFF) << endl << endl;

  // prepare to calculate the third and final little endian 16-bit checksum
  register_x = FILE02_OFFSET; // load the first offset into register X
  register_y = HALF_OF_2K;    // load 0x03FC into register Y
  accumulator = 0x6502;       // load the accumulator with the base value 6502

  while(register_y != 0){     // while Y does not equal 0 (will run 1020 times)
    accumulator += ArrayOfSRAM[register_x];      // get the first/low byte
    register_x++;                                // increment X
    accumulator += ArrayOfSRAM[register_x] << 8; // get the second/high byte
    register_x++;                                // increment X
    accumulator &= 0xFFFF;                       // discarding the carry flag
    register_y--;                                // decrement Y
  }

  // now throw the last checksum up on the console so it can also be seen
  cout << "Checksum for FILE02: " << dec << accumulator << endl;
  cout << "Little Endian HEX: " << hex << (accumulator & 0xFF) << " ";
  cout << hex << ((accumulator >> 8) & 0xFF) << endl << endl;

  // now, hold the program up until the user is done reading...
  cout << "Press ENTER to continue...";  // prompt user
  getchar();                             // wait for "ENTER" key
  return 0;                              // exit with success
}

SRAM Structure

Save slot 0 is at SRAM 0x0000, spot 1 is at 0x0800, spot 2 is at 0x1000 and there is extra space at 0x1800.
On an interesting note though, where the fourth save slot would be, the SRAM file I was working with says "Estpolis Biography Neverland Co.". A perfect 32 bytes starting at SRAM location 0x1800.

Offset Description
0x000 - 0x005 "FILE0?" where 0 is the ? for this file location in SRAM.
0x006 - 0x007 The 16 bit little endian checksum.
0x113 - 0x116 5 bytes for the Hero's name plus a null terminator (0x00).
0x119 - 0x11E 5 bytes for the Hero's name a second time plus a 0x00.
0x11F - 0x124 5 bytes for Lufia's name (once she joins) plus a 0x00.
0x125 - 0x12A 5 bytes for Aguro's name (once he joins) plus a 0x00.
0x12B - 0x12F 5 bytes for Jerin's name (once she joins) plus a 0x00.
0x131 This byte says how many party members you currently have.
0x132 - 0x134 Three bytes that contain the amount of gold your party has.
0x13E - 0x1B5 120 bytes that hold the item information.
0x1B6 Hero's Level
0x1B7 Lufia's Level
0x1B8 Aguro's Level
0x1B9 Jerin's Level
0x1C6 - 0x1C7 Hero's HP
0x1C8 - 0x1C9 Lufia's HP
0x1CA - 0x1CB Aguro's HP
0x1CC - 0x1CC Jerin's HP
0x1CE - 0x1CF Hero's MP
0x1D0 - 0x1D1 Lufia's MP
0x1D2 - 0x1D2 Aguro's MP
0x1D3 - 0x1D4 Jerin's MP
0x1D6 - 0x1F5 Hero's Magic Spells (32 bytes for 32 spells)
0x1F6 - 0x215 Lufia's Magic Spells (32 bytes for 32 spells)
0x216 - 0x235 Jerin's Magic Spells (32 bytes for 32 spells)
0x307 Hero's Equipped Weapon
0x308 Lufia's Equipped Weapon
0x309 Aguro's Equipped Weapon
0x30A Jerin's Equipped Weapon
0x30B Hero's Equipped Armor
0x30C Lufia's Equipped Armor
0x30D Aguro's Equipped Armor
0x30E Jerin's Equipped Armor
0x30F Hero's Equipped Shield
0x310 Lufia's Equipped Shield
0x311 Aguro's Equipped Shield
0x312 Jerin's Equipped Shield
0x313 Hero's Equipped Helm
0x314 Lufia's Equipped Helm
0x315 Aguro's Equipped Helm
0x316 Jerin's Equipped Helm
0x317 Hero's Equipped Shoes
0x318 Lufia's Equipped Shoes
0x319 Aguro's Equipped Shoes
0x31A Jerin's Equipped Shoes
0x31B Hero's Equipped Ring
0x31C Lufia's Equipped Ring
0x31D Aguro's Equipped Ring
0x31E Jerin's Equipped Ring

Items

You get a maximum of 5 pages of items, with 12 items a page, for a maximum of 60 items. The way the data is stored is that the first byte of the pair identifies what the item is, while the second byte of the pair identifies the quantity of that item that you have.

Value Item Name
00 Empty Slot
01 Knife
02 Club
03 Mace
04 Dagger
05 Long Knife
06 Short Sword
07 Rod
08 Gladius
09 Glass Robe
0A Brone Sword
0B Staff
0C Scimitar
0D Rapier
0E Long Sword
0F Long Staff
10 Axe
11 Spear
12 Morning Star
13 Catwhip
14 Battle Axe
15 Hammer Rod
16 Trident
17 Silver Rod
18 Silver Sword
19 Buster Sword
1A Zircon Rod
1B Great Axe
1C Grand Blade
1D Zircon Axe
1E Zircon Sword
1F Broad Sword (cursed)
20 Broad Rod (cursed)
21 Luck Blade (cursed)
22 Gloom Pick (cursed)
23 Dual Blade
24 Dress
25 Cloth
26 Cloth Armor
27 Robe
28 Tan Armor
29 Tan Robe
2A Light Armor
2B Light Robe
2C Chain Mail
2D Chain Cloth
2E Plate Cloth
2F Brone Armor
30 Quilted Silk
31 Half Mail
32 Brone Robe
33 Silver Armor
34 Silver Robe
35 Plate Mail
36 Zircon Robe
37 Zircon Armor
38 Clear Silk
39 Bracelet
3A Tan Shield
3B Wood Shield
3C Buckler
3D Wood Wrist
3E Kite Shield
3F Round Shield
40 Round Wrist
41 Brone Shield
42 Tower Shield
43 Large Shield
44 Silver Wrist
45 Silver Plate
46 Zircon Wrist
47 Zircon Plate
48 Cloth Helm
49 Tan Helm
4A Hair Band
4B Wood Helm
4C Glass Cap
4D Brone Helm
4E Red Beret
4F Iron Helm
50 Plate Cap
51 Plate Helm
52 Glass Beret
53 Silver Helm
54 Sakret
55 Zircon Beret
56 Zircon Helm
57 Sandal
58 Cloth Shoes
59 Tan Shoes
5A Spike Shoes
5B Heeled Shoes
5C Wind Shoes
5D Wind Heels
5E Knife Shoes
5F Needle Heels
60 Sonic Shoes
61 Sonic Heels
62 Sword Shoes
63 Cat Heels
64 Mach Shoes
65 Mach Heels
66 Power Ring
67 HiPower Ring
68 Daze Ring
69 Hi Daze Ring
6A Mind Ring
6B Sonic Ring
6C Mach Ring
6D Undead Ring
6E Ghost Ring
6F Dragon Ring
70 Sea Ring
71 Fly Ring
72 Water Ring
73 Fire Ring
74 Ice Ring
75 Electro Ring
76 Flash Ring
77 Flame Ring
78 Water Ring
79 Blast Ring
7A Frost Ring
7B Might Armor
7C Might Shield
7D Might Helmet
7E Gloom Ring
7F Gloom Voice
80 Dummy
81 Brone Breast
82 Carbo Sword
83 Carbo Plate
84 Carbo Shield
85 Carbo Helm
86 Carbo Cap
87 Gloom Guard
88 Diamond Ring
89 Engage Ring
8A Monster Ring
8B Blue Ring
8C Yellow Ring
8D Red Ring
8E Purple Ring
8F Green Ring
90 White Ring
91 Black Ring
92 Heavy Ring
93 Wave Ring
94 Potion
95 Hi Potion
96 Ex Potion
97 Hi Magic
98 Ex Magic
99 Antidote
9A Sweet Water
9B Foul Water
9C Awaken
9D Stone Cure
9E Mystery Pin
9F Shriek
A0 Swing Wing
A1 Magic Guard
A2 Power Gourd
A3 Mind Gourd
A4 Power Potion
A5 Spell Potion
A6 Speed Potion
A7 Mind Potion
A8 Great Potion
A9 Float
AA Smoke Ball
AB Arror
AC Mid Arrow
AD Big Arrow
AE Arrows
AF Hi Arrows
B0 Ex Arrows
B1 Dragon Arrows
B2 Sleep Arrow
B3 Puzzle Arrow
B4 Stun Arrow
B5 Gloom Arrow
B6 Bomb
B7 Hi Bomb
B8 Ex Bomb
B9 Miracle
BA Revive
BB Pear Cider
BC Sour Cider
BD Lime Cider
BE Plum Cider
BF Apple Cider
C0 Hair Band
C1 Brooch
C2 Earring
C3 Necklace
C4 Stuffed Bear
C5 Stuffed Dog
C6 Stuffed Pig
C7 Emerald
C8 Opal
C9 Goblet
CA Ear Tip
CB Empty Bottle
CC Gown
CD Ribbon
CE Fry Pan
CF Small Knife
D0 Pot
D1 Chop Block
D2 Apron
D3 Dragon Egg
D4 Crown
D5 Secret Map
D6 Miracle Gem
D7 Silver Wick
D8 Royal Statue
D9 Silver Tarot
DA Golden Pawn
DB Crown Jewels
DC Wind Flute
DD Escape
DE Magic Jar
DF Dragon Tooth
E0 Grilled Newt
E1 Poison Pin
E2 Might Sword
E3 Straw Doll
E4 Long Nail
E5 Bomb
E6 Alumina
E7 Power Oil
E8 Elven Bow
E9 Artea's Bow
EA Might Bow
EB Dummy
EC Dummy
ED Dummy
EE Dummy
EF Free Door
F0 Sheran Key
F1 Letter
F2 Dais Key
F3 Shrine Key
F4 Pirate Key
F5 Light Key
F6 Oil Key
F7 Green Jade
F8 Red Sapphire
F9 Blue Jade
FA Purple Newt
FB Glasdar Key
FC Magic Flavor
FD Fairy Kiss
FE Not Used
FF Not Used

Note that there is some oddity in this list, such as two items named "Bomb", and at least 5 "Dummy" items, and then there's "Free Door" on top of that.

Not only that, but several of these items, such as "Sheran Key", go into your Scenario page, not your item list. But, I digress -- you can add them in to your SRAM file anyway.

Magic

You have a maximum amount of space for spells of 32 bytes. However, the way that magic works is that the spell listing must end with a call to 0x00 for "END OF LIST". Otherwise, if you use up all 32 slots in Hero's Magic list, he will also have every spell of Lufia's in his spell casting ability as well! And likewise, if you fill up all 32 of Lufia's spells, you can spill over into Jerin's territory. And if you fill up Jerin's... Well, you'll probably crash something, but just beware if you go to edit the game in this manner. Though with this method, you can actually give your Hero EVERY spell in the game when the team consists of only you and Lufia! Also, notice that there is no space reserved for Aguro to have magic, so you cannot just give him some spells to let him cast away.

Value Description
00 END OF LIST
01 Flash
02 Bolt
03 Thunder
04 Spark
05 Flame
06 vulcan
07 Dew
08 Water
09 Flood
0A Bang
0B Blast
0C Sunder
0D Frost
0E Blizzard
0F Glacier
10 Perish
11 Succumb
12 Drowsy
13 Fright
14 Drain
15 Dread
16 Deflect
17 Bounce
18 Absorb
19 Fake
1A Trick
1B Confuse
1C Bravery
1D Courage
1E Shield
1F Protect
20 Mirror
21 Statue
22 Strong
23 Stronger
24 Champion
25 Boost
26 Valor
27 Poison
28 Stun
29 Dead
2A Rally
2B Stone
2C Waken
2D Warp
2E Escape
2F Float
30 Elf
31 Defake
32 Figual
33 Paraiz
34 Elegion
35 Elegi
36 Elegio
37 Absobl

In case you do not recognize some of the last magic spells on that list, that is because they must have been in there for test purposes. Without going too much off topic, here is what it appears that these extra magic spells do:

  • Defake - Agility Down
  • Figual - Confuse
  • Paraiz - Paralyze
  • Elegion - Thunder Spell (all enemies)
  • Elegi - Flash Spell (all enemies)
  • Elegio - Bolt Spell (all enemies)
  • Absobl - Absorb Magic

The plus of some of these spells is that they cost only 1 or no MP at all to cast, meaning you can give them to your low level party and completely rule the entire game -- never mind the great items you could give yourself as well.

Dictionary Reference Key

The dictionary is located at 0x054E19 - 0x0553CC.

Ì, .z .& .îone.. a fake ..?. ..   rich ‡ gemstone.mines. Ì .o ran .‹..` ago.

Can't read some of those characters? Well, that's because the stuff that doesn't make sense has to do with punctuation and pointers to other words that get put in place.

The statement that should be making is this:

But, why would anyone
make a fake ruby?
Medan was rich in gemstone
mines. But they ran out
years ago.

A few words are there that you can make out (between some towns person and the Princess in Medan). Such as ",", "one", "a fake", "?", "rich", "gemstone mines.", "ran", "ago.". But what about the questionable things you can't see. Let's take the first part, the "But, why would anyone make a fake ruby, which looks like this, and compare it against the dictionary file of the game (0x54A50):

cc 2c 20 0c 7a 20 0c 26 20 0c ee 6f 6e 65 05 0c 7f 20 61 20 66 61 6b 65 20 0c 19 3f

Ì, .z .& .îone.. a fake ..?. 

cc    -> refers to an upper case "But"
2c    -> comma (",")
20    -> blank space
0c 7a -> refers to a lower case (0c is "lower case"/0d is "upper case") "why"
20    -> blank space
0c 26 -> refers to a lower case "would"
20    -> blank space
0c ee -> refers to a lower case "any"
6f    -> letter "o"
6e    -> letter "n"
65    -> letter "e"
05    -> line/carriage return
0c 7f -> refers to a lower case "make"
20    -> blank space
61    -> letter "a"
20    -> blank space
66    -> "f"
61    -> "a"
6b    -> "k"
65    -> "e"
20    -> blank space
0c 19 -> refers to a lower case "ruby"
3f    -> "?"

But, why would anyone
make a fake ruby?

After that, there is a "04 A0" code which I can only assume is some sort of "close textbox" and "open new text box" (and possibly a character sprite/on screen location to hook it to). But then we get to the second phrase:

0b 08 20 a0 20 72 69 63 68 20 87 20 67 65 6d 73 74 6f 6e 65 05 6d 69 6e 65 73 2e 20 cc 20 0c 6f 20 72 61 6e 20 0c 8b 05 0c 60 20 61 67 6f 2e

..   rich ‡ gemstone.mines. Ì .o ran .‹..` ago.

0b 08                   -> dictionary for the town name "Medan"
20                      -> blank space
a0                      -> lower case "was" (notice it is not referenced by any 0c/0d type calls)
20                      -> blank space
72                      -> "r"
69                      -> "i"
63                      -> "c"
68                      -> "h"
20                      -> blank space
87                      -> lower case "in"
20                      -> blank space
67 65 6d 73 74 6f 6e 65 -> letters for "gemstone"
05                      -> carriage/line return
6d 69 6e 65 73          -> letters for "mines"
2e                      -> "."
20                      -> blank space
cc                      -> upper case "But" (as 8c refers to lower case)
20                      -> blank space
0c 6f                   -> lower case "they"
20                      -> blank space
72 61 6e                -> letters for "ran"
20                      -> blank space
0c 8b                   -> lower case "out"
05                      -> carriage/line return
0c 60                   -> lower case "years"
20                      -> blank space
61 67 6f                -> letters for "ago"
2e                      -> "."

Medan was rich in gemstone
mines. But they ran out
years ago.

Then there's more words after that, because she's long winded, but you get the idea... It took me almost 8 hours of trial and error to figure out how the dictionary words were stored, as well as what numbers called them (which I figured out by comparing the dictionary against known phrases). The upper case/lower case was a bit harder to figure out as well. There's still some extra data that doesn't make sense yet. Also, there's a lot of words that are in the dictionary but they don't both to make a call to use them (like "one" in the above example"). There must be a reason for this, but I have yet to figure it out.

Some things are a little more hidden, such as a character is referenced by "07 0X" with Hero being "07 00" up to Gades as "07 0b". Also, while to get lowercase/uppercase for the one set of dictionary words it seems to be dependent on the "0c" vs. "0d" call, the other section of dictionary words has two memory addresses that are separate for lower case or upper case (though the dictionary only exists once, it just loops back on itself I guess). For example, in the non-0c/0d dictionary, the word "there" is referenced by "8e", while "There" is referenced by "ce". Meaning they're exactly 0x40 difference.

Now, for the dictionaries themselves, the character names start around "0xe800", the town names around "0xe850", there's one of 16 words (such as ('s) and ("Welcome")). These start at "0x54a50". Then the next dictionary (the one that has double calls to it, for being lower case/upper case) starts at "0x54ac0" (it contains 80 items, which makes for 160 words between upper/lower case). Then the main dictionary (called by 0c/0d for lower/upper case) starts near "0x54c10". Now, there's two types of dictionary calls here.

Early on names:

0xe850:    8f e8 95 e8 9b e8

8f e8 refers to memory location "0xe88f", which contains the name "Alekia"
95 e8 refers to memory location "0xe895", which contains the name "Chatam" 
9b e8 refers to memory location "0xe89b", which contains the name "Sheran"

These places are called by text boxes by "0b xx", where "0b 01" is Alekia, "0b 02" is Chatam, "0b 03" is Sheran and so on (there's an extra space '.' in this list which makes the names start at 1 instead of 0).

Later on words:

0x54ac0:    42 cb 45 cb 48 cb

Here we have a bit of a problem, as memory location "0xcb42" is way back in the program and nowhere near what we want. So all of these later dictionary entries need to have the hex value "0x48000" added to them so that they point to the proper place. The unique item grabber program I made for Diablo I uses a pointer offset like this too, so it is not all that uncommon for larger programs, especially later on in the data when dealing with 16 bit little endian pointers.

42 cb + 48000H = "0x54b42" which contains the word "the"
45 cb + 48000H = "0x54b45" which contains the word "you"
48 cb + 48000H = "0x54b48" which contains the word "to"

In case you didn't notice, the pointer to the next word tells you where to stop. At least, that's my guess...

Important Codes

Values Description
04 Text Box Close (?)
05 Line Return
07 Character Name Call
0B Place Name Call
0C Lower Case Dictionary
0D Upper Case Dictionary
20 Blank Space (" ")
2E Period (.)
2B Double Period (..)
20 - 7F Reserved Character Symbols
00 - 0F Reserved Flag Calls and Specials
80 - A9 New Textbox (?) (Tie to Character/Position?)
?? Time to Wait Between Boxes (?)
Value Name
07 00 Hero
07 01 Lufia
07 02 Aguro
07 03 Jerin
07 04 Maxim
07 05 Selan
07 06 Guy
07 07 Artea
07 08 Daos
07 09 Erim
07 0A Amon
07 0B Gades
Values Name
1C E8 Lufia
21 E8 Aguro
26 E8 Jerin
2B E8 Maxim
30 E8 Selan
35 E8 Guy
38 E8 Artea
3D E8 Daos
41 E8 Erim
45 E8 Amon
49 E8 Gades
4E E8 <- End of List
Value A Value B Names
00 8E E8 (00)
01 8F E8 Alekia
02 95 E8 Chatam
03 9B E8 Sheran
04 A1 E8 Treck
05 A6 E8 Lorbenia
06 AE E8 Grenoble
07 B6 E8 Kirof
08 BB E8 Medan
09 C0 E8 Surinagal
0A C9 E8 Belgen
0B CF E8 Jenoba
0C D5 E8 Ruan
0D D9 E8 Ranqs
0E DE E8 Odel
0F E2 E8 Lyden
10 E7 E8 Arus
11 EB E8 Platina
12 F2 E8 Carbis
13 F8 E8 Bakku
14 FD E8 Linze
15 02 E9 Marse
16 07 E9 Herat
17 0C E9 Soshette
18 14 E9 Epro
19 18 E9 Arubus
1A 1E E9 Frederia
1B 26 E9 Forfeit
1C 2D E9 Makao
1D 32 E9 Elfrea
1E 38 E9 Elfrea
XX 3E E9 <- End of List

Offset: 048000 (hex)

Values Link # Dictionary
10 72 CA 's
11 74 CA ed
12 76 CA ing
13 79 CA I'm
14 7C CA I'll
15 80 CA I've
16 84 CA Alumina
17 8B CA Sinistral
18 94 CA Dual
19 98 CA Falcon
1A 9E CA Glasdar
1B A5 CA Welcome
1C AC CA Raile
1D B1 CA Lilah
1E B6 CA Reyna
1F BB CA Shaia
XX C0 CA <- End of List
LC UC Link # Dictionary
80 C0 42 CB the
81 C1 45 CB you
82 C2 48 CB to
83 C3 4A CB it
84 C4 4C CB of
85 C5 4E CB that
86 C6 52 CB is
87 C7 54 CB in
88 C8 56 CB and
89 C9 59 CB what
8A CA 5D CB this
8B CB 61 CB go
8C CC 63 CB but
8D CD 66 CB are
8E CE 69 CB there
8F CF 6E CB no
90 D0 70 CB be
91 D1 72 CB we
92 D2 74 CB so
93 D3 76 CB do
94 D4 78 CB for
95 D5 7B CB have
96 D6 7F CB can
97 D7 82 CB me
98 D8 84 CB know
99 D9 88 CB don't
9A DA 8D CB he
9B DB 8F CB if
9C DC 91 CB my
9D DD 93 CB here
9E DE 97 CB yes
9F DF 9A CB on
A0 E0 9C CB was
A1 E1 9F CB island
A2 E2 A5 CB with
A3 E3 A9 CB about
A4 E4 AE CB your
A5 E5 B2 CB come
A6 E6 B6 CB get
A7 E7 B9 CB see
A8 E8 BC CB can't
A9 E9 C1 CB will
AA EA C5 CB right
AB EB CA CB now
AC EC CD CB let
AD ED D0 CB ok
AE EE D2 CB at
AF EF D4 CB take
B0 F0 D8 CB just
B1 F1 DC CB up
B2 F2 DE CB really
B3 F3 E4 CB please
B4 F4 EA CB well
B5 F5 EE CB not
B6 F6 F1 CB all
B7 F7 F4 CB you're
B8 F8 FA CB good
B9 F9 FE CB want
BA FA 02 CC four
BB FB 06 CC tower
BC FC 0B CC as
BD FD 0D CC from
BE FE 11 CC back
BF FF 15 CC by
XX XX 17 CC <- End of List
"0c" -> lc
"0d" -> uc
Value Link # Dictionary
00 19 CE something
01 22 CE monsters
02 2A CE professor
03 33 CE doom
04 37 CE pieces
05 3D CE lorbenia
06 45 CE vibration
07 4E CE basement
08 56 CE village
09 5D CE going
0A 62 CE understand
0B 6C CE around
0C 72 CE you'll
0D 78 CE should
0E 7E CE dangerous
0F 87 CE think
10 8C CE people
11 92 CE cave
12 96 CE find
13 9A CE castle
14 A0 CE again
15 A5 CE gold
16 A9 CE won't
17 AE CE power
18 B3 CE north
19 B8 CE ruby
1A BC CE blade
1B C1 CE return
1C C7 CE battle
1D CD CE where
1E D2 CE when
1F D6 CE you've
20 DC CE together
21 E4 CE through
22 EB CE still
23 F0 CE doesn't
24 F7 CE sapphires
25 00 CF yourself
26 08 CF would
27 0D CF anything
28 15 CF never
29 1A CF because
2A 21 CF didn't
2B 27 CF been
2C 2B CF nothing
2D 32 CF lever
2E 37 CF hello
2F 3C CF alright
30 43 CF thanks
31 49 CF little
32 4F CF descendant
33 59 CF course
34 5F CF only
35 63 CF before
36 69 CF town
37 6D CF some
38 71 CF remember
39 79 CF kingdom
3A 80 CF recently
3B 88 CF great
3C 8D CF wish
3D 91 CF strong
3E 97 CF without
3F 9E CF treasure
40 A6 CF time
41 AA CF thought
42 B1 CF strange
43 B8 CF looking
44 BF CF heard
45 C4 CF over
46 C8 CF today
47 CD CF tell
48 D1 CF look
49 D5 CF like
4A D9 CF believe
4B E0 CF restored
4C E8 CF help
4D EC CF father
4E F2 CF always
4F F8 CF wonder
50 FE CF must
51 02 D0 matter
52 08 D0 king
53 0C D0 everything
54 16 D0 country
55 1D D0 we're
56 22 D0 sorry
57 27 D0 night
58 2C D0 need
59 30 D0 happened
5A 38 D0 found
5B 3D D0 everyone
5C 45 D0 shop
5D 49 D0 even
5E 4D D0 thank
5F 52 D0 someone
60 59 D0 years
61 5E D0 world
62 63 D0 vibrations
63 6D D0 true
64 71 D0 saying
65 77 D0 returned
66 7F D0 princess
67 87 D0 isn't
68 8C D0 aren't
69 92 D0 worried
6A 99 D0 they're
6B A0 D0 destroy
6C A7 D0 one
6D AA D0 lately
6E B0 D0 wouldn't
6F B8 D0 they
70 BC D0 said
71 C0 D0 leave
72 C5 D0 couldn't
73 CD D0 things
74 D3 D0 sure
75 D7 D0 many
76 DB D0 enough
77 E1 D0 hope
78 E5 D0 give
79 E9 D0 too
7A EC D0 why
7B EF D0 who
7C F2 D0 then
7D F6 D0 stay
7E FA D0 rubies
7F 00 D1 make
80 04 D1 maberia
81 0B D1 long
82 0F D1 cinnamon
83 17 D1 careful
84 1E D1 attacked
85 26 D1 anyway
86 2C D1 she
87 2F D1 more
88 33 D1 three
89 38 D1 these
8A 3D D1 south
8B 42 D1 out
8C 45 D1 first
8D 4A D1 after
8E 4F D1 sacrifice
8F 58 D1 reward
90 5E D1 man
91 61 D1 how
92 64 D1 fine
93 68 D1 cooper
94 6E D1 knights
95 75 D1 west
96 79 D1 stop
97 7D D1 magic
98 82 D1 level
99 87 D1 could
9A 8C D1 ahead
9B 91 D1 used
9C 95 D1 him
9D 98 D1 called
9E 9E D1 wrong
9F A3 D1 we'll
A0 A8 D1 place
A1 AD D1 floor
A2 B2 D1 bring
A3 B7 D1 brant
A4 BC D1 such
A5 C0 D1 ship
A6 C4 D1 mean
A7 C8 D1 islands
A8 CF D1 into
A9 D3 D1 came
AA D7 D1 already
AB DE D1 wonderful
AC E7 D1 southeast
AD F0 D1 northwest
AE F9 D1 commander
AF 02 D2 apologize
B0 0B D2 whatever
B1 13 D2 wanted
B2 19 D2 them
B3 1D D2 switch
B4 23 D2 sapphire
B5 2B D2 might
B6 30 D2 later
B7 35 D2 forest
B8 3B D2 fight
B9 40 D2 city
BA 44 D2 bridge
BB 4A D2 way
BC 4D D2 got
BD 50 D2 old
BE 53 D2 mark
BF 57 D2 feel
C0 5B D2 down
C1 5F D2 did
C2 62 D2 we've
C3 67 D2 small
C4 6C D2 seems
C5 71 D2 other
C6 76 D2 light
C7 7B D2 haven't
C8 82 D2 has
C9 85 D2 forgive
CA 8C D2 were
CB 90 D2 spirit
CC 96 D2 shrine
CD 9C D2 happen
CE A2 D2 under
CF A7 D2 things
D0 AC D2 supposed
D1 B4 D2 spiritual
D2 BD D2 southwest
D3 C6 D2 shouldn't
D4 CF D2 possible
D5 D7 D2 medicine
D6 DF D2 left
D7 E3 D2 knows
D8 E8 D2 important
D9 F1 D2 care
DA F5 D2 away
DB F9 D2 alone
DC FE D2 surrounded
DD 08 D3 say
DE 0B D3 repair
DF 11 D3 problem
E0 18 D3 much
E1 1C D3 memory
E2 22 D3 girlfriend
E3 2C D3 girl
E4 30 D3 gets
E5 34 D3 defeat
E6 3A D3 better
E7 40 D3 anytime
E8 47 D3 young
E9 4C D3 raise
EA 51 D3 piron
EB 56 D3 yeah
EC 5A D3 wait
ED 5E D3 best
EE 62 D3 any
EF 65 D3 tunnel
F0 6B D3 second
F1 71 D3 order
F2 76 D3 mountain
F3 7E D3 memories
F4 86 D3 makes
F5 8B D3 made
F6 8F D3 live
F7 93 D3 kill
F8 97 D3 items
F9 9C D3 information
FA A7 D3 hey
FB AA D3 her
FC AD D3 grief
FD B2 D3 disappeared
FE BD D3 daughter
FF C5 D3 business
XX CD D3 <- end of list

SRAM details algorithm description, C++ checksum program and text dictionary compression by Vegetaman. SRAM Checksum traced and described by KingMike.