General notes ============= Font palette: - Standard text windows: 0x4 = background, 0xF = foreground - File select/setup windows: 0x1 = background, 0x9 = foreground Hard-coded characters: - 0xFD: bullet (tile 0x1DD) - 0xFE: equip (tile 0x1DE) - Null (tile 0x1DF) - Background (tile 0x1FF) - 0xB4 - 0xBC: YOU WON! (tile 0x154) English names: - Ness: 7E 95 A3 A3 - Pala: 80 91 9C 91 - Jeff: 7A 95 96 96 - Poo: 80 9F 9F 0x2020C70: enemy data slots in-battle? separated by 0x94 bytes 0x2025038: enemy count (initial, not current) 0x20251D8: item drop 0x3000A00: Current PSI list when displaying a PSI window? 0x3000AA0: currently selected party member e.g. when in the Goods windows (-1 if nobody selected) 0x3000AA2: number of party members 0x3001300: number to be printed (e.g. withdrawn money amount) 0x300130C: window flags? - 0x0800 is set when any of the A-menu sub-windows are open (Goods, PSI, etc.) - 0x0001 is set when the A-menu is open - 0x0002 is set when the cash window is open? or hp/pp maybe? - 0x0007 is set when the main text window is open 0x3001D54: Ness items (16 bits each) 0x3001D70: Ness EXP 0x3001D80: Ness level 0x3001D84: Ness max HP 0x3001D86: Ness current HP 0x3001D8C: Ness max PP 0x3001D8E: Ness current PP 0x3001D94: Ailment? 00: conscious 01: unconscious 02: diamondized 03: paralyzed 04: nauseous 05: poisoned 06: sunstroke 07: sniffling 08: mashroomized 09: possessed 0A: homesick 0x3001D95: Mashroomized flag? 0x3001D96: Sleep flag? 0x3001D97: Strange flag? 0x3001D98: Can't concentrate flag? 0x3001D99: Homesick flag? 0x3001DA3: Ness offense 0x3001DA4: Ness defense 0x3001DA5: Ness speed 0x3001DA6: Ness guts 0x3001DA7: Ness luck 0x3001DA8: Ness vitality 0x3001DA9: Ness IQ 0x3001DB5: Ness equipment 0x3001F04: Current party 0x3001F0B: Party character count (not sure how it's different from 3000AA2?) 0x3001F0C: Active party member flags 0x3001F6A: Ness PSI flags? 0x01: Teleport alpha 0x08: Teleport beta 0x3001FA4: Escargo Express items (36 of them) 0x3001FC8: event flags 0x30023D0: current cash balance 0x30023D4: current ATM balance 0x3002500: buttons being pressed 0x3002504: shadow of 0x3002500? delayed by one frame maybe? 0x3004F08: printing flag 0x30051EC: tile offset (usually 0x100) 0x30051F0: flag? gets set to 1 when you change rooms, goes back to 0 the first time you open a text window 0x3005224: menu sub-state - Equip: - 01: character select - 02: slot select - 03: Weapon select - 04: Body select - 05: Arms select - 06: Other select - PSI: - 01: character select - 02: PSI select - 03: target select - 04: text box 0x3005228: current text palette, << 0xC 0x3005230: addresses of all 11 windows [00]: A menu [01]: Money [02]: ? [03]: Action subject ("Who?", etc.) [04]: New equipment selection [05]: Offense/Defense [06]: Equip [07]: PSI list [08]: PSI classes [09]: PSI target/PP cost [0A]: PSI help 0x3005264: active window party member 0x3005270: address of tilemap start in WRAM, can use this to figure out X and Y 0x872E404: door destinations? LDRB Rx,[Ry,#n]: n has range 0-31 (0x0-0x1F) LDRH Rx,[Ry,#n]: n has range 0-62 (0x0-0x3E) LDR Rx,[Ry,#n]: n has range 0-124 (0x0-0x7C) (0-1020 for SP- and PC-relative) Custom WRAM: 2027FC0 Game code: ~0x0 - ~0x264FB Movement-y stuff?: ~0x264FC - ~0x3697E Text: 0x3697F - 0x8C4B0 More code: 0xA1F6C - 0xFCE6B EarthBound, Ness' Items: 7E99F1 Code sequences -------------- 80BAB64: draw and render PSI party target window 80C4C24: equip window renders four (None)s in a row 80C4F80: going left in equip window 80C4F84: going right in equip window Subroutines ----------- 8001720: play sound effect r0 8005B9C: malloc? r0 = byte count 801C104: return random number from 0 to r0 (exclusive) 80A2E00: door-related? r0 = source, r1 = dest 80A334C: store r0 to window memory 80B8AE0: draw PSI target/PP cost window with PSI index r0 80BB268: Weapons window 80BC670: check if currently selected character has item equipped r0: item index + 1 returns: 1 if equipped, 0 otherwise or if index==0 80BD7AC: copy window buffer (primary/secondary) r0 = 0: copy from primary (2028A58) to secondary (2030A40) r0 = 1: copy from secondary to primary 80BD7F8: copy window buffer (primary/tertiary) r0 = 0: copy from primary (2028A58) to tertiary (2031248) r0 = 1: copy from tertiary to primary 80BE260: compute string pointer r0: pointer table r1: text base r2: index 80BE458: initialize window. If text pointer == 0, also draw window borders. r0: window pointer r1: text pointer r2: mystery halfword that gets copied to +0x2E 80BE4C8: initialize window. If text pointer == 0, also draw window borders. r0: window pointer r1: text pointer r2: mystery byte that gets copied to +0x42 r3: mystery halfword that gets copied to +0x3E sp+0: mystery halfword that gets copied to +0x34 and +0x40 if the window enable flag is unset 80BF858: goods character selector state machine r0: window pointer returns: 0 if no action, 1 if descending deeper into window, -1 if exited 80C0420: goods character selector state machine (escargo express check-out from Tracy) seems to be identical to 80BF858 except that the window is shifted down by one tile, and the text is shifted down another tile so that it renders properly r0: window pointer returns: 0 if no action, 1 if A/L pressed, -1 if B/select pressed 80C0A5C: render numbers on status window 80C1FBC: draw PSI window for character r0 80C239C: print PSI name with Greek letter 80C438C: check for cursor movements in PSI window 80C5B10: If everything works properly, changes cursor position in Weapons/Body/Head/Other submenu 80C87D0: draw blank window and border (r0: window pointer) 80C8BE4: render main menu string to window r0 80C8FFC: render string to window r0 80C9634: render string (r1) to window (r0) at (x,y) (r2,r3) 80C96F0: render string (r1) to window (r0) at (x,2y) (r2,r3) using highlight [sp] (does not modify any window values) 80C980C: print next character (r0: window pointer) 80CA4BC: scroll text upwards (r0: window pointer) 80CA65C: format a number as a string (does not write [00 FF]) r0: number r1: output string buffer r2: limit to r2 decimal digits (will clip to 10^r2 - 1) returns: -1 if clipped, 0 otherwise 80CA744: store the lowest r2 (e.g. 7) decimal digits of r0 as an array to r1; return position of highest non-zero digit 80CAB90: print window header string (r1) to RAM (r0) at tile ((r2 * 32) + r3) 80CABF8: print checkboard string (r1) to RAM (r0) at tile ((r2 * 32) + r3) 80D2E94: print party character name 80D30C4: related to printing numbers points in battle (r0 = window) 80D31F8: related to printing numbers outside of battle (r0 = window) 80D332C: related to printing names in battle (r0 = window) 80D3560: related to printing numbers outside of battle (r0 = window) 80D3858: related to printing numbers 80D3F0C: bump the HP/PP window of the given party member upwards r0: party member index 80D41D8: bump the HP/PP window of the current party member downwards 80D7154: count party members and store to 3000AA2 then do some other stuff to the windows -- possibly drawing the HP/PP boxes? 80EBFD4: copy string from r0, of max length r1, to battle user slot, and terminate with [00 FF] 80EC004: get user string pointer 80EC010: copy string from r0, of max length r1, to battle target slot, and terminate with [00 FF] 80EC046: get target string pointer 80F49DC: divide r0 by r1, return quotient in r0 8B1B8B8 has a jump table with 13 entries for the [1A FF xx 00] code: 00: ? 01: PC name 02: item name 03: ? 04: number 05: PC name 06: ? 07: ? 08: ? 09: ? 0A: ? 0B: ? Windows ------- Window structure: 0x00 - 0x03: bitfield 0x00000001: enable 0x00000010: ? (checked when going right in goods character selection menu) 0x00000020: signals to redraw the window and borders (cleared by C87D0) 0x0000FFCE: ? 0xFFFF0000: we're stealing these for our hacks 0x0007: pixel X value 0xFFF8: unused 0x04 - 0x07: start address of text being displayed 0x08 - 0x0B: same as above? 0x0C - 0x0F: menu text pointer 0x10 - 0x13: ? 0x14 - 0x17: text address offset 0x18 - 0x1B: ? 0x1C - 0x1F: when printing numbers: the current digit index to print when printing names: ? 0x20 - 0x21: area (width*height) 0x22 - 0x23: window X (text area, not including border) 0x24 - 0x25: window Y 0x26 - 0x27: window width (tiles, not including border) 0x28 - 0x29: window height 0x2A - 0x2B: relative text X 0x2C - 0x2D: relative text Y 0x2E - 0x2F: ? 0x30 - 0x31: frame delay counter (counts down to 0, once per frame, after calling 1B FF xx xx) 0x32 - 0x33: frame counter? e.g. for goods windows, it counts up to 0x10 and then loops back to 0 0x34 - 0x35: cursor X 0x36 - 0x37: cursor Y 0x38 - 0x39: ? 0x3A - 0x3B: ? 0x3C - 0x3D: ? 0x3E - 0x3F: ? 0x40 - 0x41: page number? 0x42 : cursor delta 0x43 : unused? 0x44 - 0x4F: ? Custom codes ------------ 5E FF xx: load value into memory 01: plurality of enemies: 01 = one 02 = two 03 = three or more 5F FF xx: set current rendering location to xx 60 FF xx: add xx to current rendering location Enemy data ---------- $8739D1C - $873D6DB Default names --------- 0x82B9330 - 0x82BA1BB contains the default names. Each single default name is 0x4C bytes long. Each character's default names list is 0x214 bytes long, so each character has 7 possible default names. First 4 bytes are the name's length. After that there is the name. There are 7 character's entries. --------- Around the zone near 0x802A753 there seems to be scripting data. (This one in particular is Carpainter's lightning script data) Control code [06 XX] makes it so the game doesn't read from the script for XX frames.