This isn't complete enough to get a page yet, but it's still interesting and worth sharing so let's write down some of the memory regions.
Disclaimer: Double check the addresses - some of them end up off by a bit if I misread a structure or forget to check the main DU address
Memory locations and format[]
A note about these pointers: These all point to what I am calling "Data Units" because the start of each is 0x44,0x55,0x00,0x00 "DU\0\0" followed by a size, a pointer to the previous/next unit, and a pointer to the next/previous unit. It looks like a doubly-linked list, maybe it's related to memory allocation? Some of these addresses/sizes may change if you load/save files. My (successful) tests always go Launch PTC -> Write Program. If I scan a QR code first, it seems random whether or not the addresses have all shifted by a couple hundred bytes. If you need a consistent way to get pointers, the "main DU" contains pointers to a variety of useful other DUs.
Most of these locations seem to be buffers where you first need to get PTC to update to make display changes take effect. For example, writing to the GRP0 DU will not immediately display changes, but running GPAGE 0,1,1:GPAGE 0,0,0
after will update the display.
The following table omits some data units that didn't have any clear purpose or seemed to be metadata.
DU Address | Size | Purpose/Assumed purpose | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0217ff40 | 0x00c948 | Seems to contain several things and be a sort of "primary DU". Contains pointers to many important structures, like the variable, array, string DUs, etc.
Expressions entered in DIRECT mode show up at 0x0217ff60 with a bit of info before and after. At 0x021804b0, you can find the startup text for DIRECT mode (i.e. "PetitComputer ver2.2", etc. in UCS2). At 0x02181d74, you can find previous commands entered into DIRECT mode, in an array of 0x40 byte (32 character) UCS2 strings. At 0x02185e28, you can find the function key text in units of 0x200 byte (256 character) UCS2 strings. At 0x02186854, you can a list of commands in the same order as the special characters table listed at the bottom of this page. This table seems to consist of elements of the following form
This may be how PTC determines what code is called for each command. At about 0x021894f8, there seems to be a some sort of temporary string data? (From output of expressions or commands?) At 0x0218be70, the function table exists in the same format as the command table. At 0x0218c4fc, the sysvar table exists in the same format as the command table, and goes until the end of this DU. | ||||||||||||||||
0x0218c8c8 | 0x028b38 | This one contains "RTFN" "FNIF" "PLGC" sections. This is the "Nitro Font Resource" according to GBAtek; so this is probably the font used. | ||||||||||||||||
0x021b5434 | 0x113884 | Contains program data and line number info.
The program data is stored in UCS2 like MEM strings, but with commands, functions, etc. replaced with special characters. See this page if it ever comes back up, or alternatively see the table at the bottom of this page which is copied from there. The line number info is after the size 0x100000 block of memory corresponding to the program data. It seems that the above program data is not necessarily ordered - the line data appears to be two four-byte numbers per line, corresponding to starting offset and number of characters. It is possible to have lines added to the end of the program appear at the beginning of this region. The program size seems to be based on bytes and not characters, so you can fill more than 524288 (visual) characters if you use lots of commands that compress well. For example, filling the program space with "CLEAR " x14 per line x9998 lines is approaching a million visible characters, yet doesn't run out of memory because the data is stored as 0d e0 0d e0 0d e0 ..., which is much less memory at 30 bytes x 9998. | ||||||||||||||||
0x022c8cc8 | 0x208008 | A (linked?) list of various strings. This seems to be how all unique strings are stored, as the size matches the 0x1000 (4096) strings * 0x100 (256) characters/string * 0x2 bytes/character -> 0x200000 bytes + 0x8 bytes (one pointer to previous string + unknown 2 bytes, 2 bytes that match length in characters?) * 0x1000 strings + 0x8 bytes at the end (one pointer to somewhere in the middle of this DU, and one pointer to 0x0217ff50 (common address with currently unknown purpose)
| ||||||||||||||||
0x024d0ce0 | 0x01b004 | This contains variable memory.
First byte is number of variables; second is empty; then begins an array of 2048 entries of the below format. Entries are defined in the order variables are used. CLEAR zeros out the names and values, but not the unknown value or the specific type/length pair. Each entry is 52(?) bytes long:
There may be more of differing format past the end of this. Last 0x0ffc(?) bytes contains pointers into the above entries, to the unknown value. | ||||||||||||||||
0x024ebcf4 | 0x10800c | Array memory. First 0x8000 defines arrays, next 0x100000 holds array contents
The array defines contain the following information in units of 0x10 bytes
The actual array data is stored at the offset given. The array data is stored with the second dimension first, if applicable (a[x,y] is followed by a[x,y+1], for example.) | ||||||||||||||||
0x025f3c70 | 0x06c770 | Contains several strings that matched variable names, currently unknown purpose. Past those are several sets of 21 0x0000s followed by 0xffff. | ||||||||||||||||
0x026654d4 | 0x009930 | This contains sprite data in the same form as the OAM at 0x026655e0 (upper screen) and 0x026659e0 (lower screen). This seems to contain some other additional information before and after that, but I have not figured out what yet. Possibly sprite animation info, sprite variables, collision data? | ||||||||||||||||
0x0266ee60 | 0x002000 | SCU1U tile data | ||||||||||||||||
0x02670ebc | 0x002000 | SCU0U tile data | ||||||||||||||||
0x02676fcc | 0x00c00c | GRP0 data. There's a little extra at the end for some reason, not clear what it's for yet. | ||||||||||||||||
0x02682fe8 | 0x00c00c | GRP1 | ||||||||||||||||
0x0268f004 | 0x00c00c | GRP2 | ||||||||||||||||
0x0269b020 | 0x00c00c | GRP3 | ||||||||||||||||
0x02747ff0 | 0x001940 | 0x0274804c: Console character info -> changes made here are reflected when the console gets updated as well (this is the source that is used to update the tile data). Replaced when entering program editor.
0x0274931c: Console color information (not replaced in editor for some reason; used to set tile data) 0x02794638: Console BG color information (not replaced in editor for some reason; used to set tile data) | ||||||||||||||||
0x0274998c | 0x002000 | Program console (tile) data. This includes the program editor's text and the regular text console. Note that modifications made here seem to be lost after updates; the actual permanent console data is located before in the previous DU. | ||||||||||||||||
0x0274b9e8 | 0x002000 | Program editor background data. Only used in the editor, I think? |
Additionally, see GBATEK - GBA/NDS Technical Info for a variety of other information that may be of interest.
VRAM notes[]
Unlike the buffered locations above, writing to VRAM can get changes to take effect immediately, so here's a list of those interesting addresses. However, PTC may overwrite some of these changes from it's buffered data. It currently seems like character data is only stored here (if you modify it the result is accessible from CHRREAD
) while the text/BG pages seem buffered (Texf FG modifications are lost upon updating the console normally, for example).
Note that every 0x20000 is mirrored for all these VRAM addresses. You could write to 0x06020000 to write to the upper screen text console, for example.
Address | Size | Data | Useful info |
---|---|---|---|
0x06000000 | 0x2000 | Upper screen text screen FG | This is the console text screen, which means if you write here you can apply horizontal or vertical flips to text, as well as set normally inaccessible character codes 512-1023. Uses BGF resources, with 512+ being duplicates of the first 512. |
0x06002000 | 0x2000 | Upper screen text screen BG | This is used for the code editor background grid, as well as background colors ex. from COLOR 0,3 . If you write to this, you could set unique background colors, or instead set background tiles. Uses BGD resources.
|
0x06004000 | 0x2000 | Upper screen BG0 layer | It's the standard BG layer. Everything here can already be controlled from PTC, uses BGU resources. |
0x06006000 | 0x2000 | Upper screen BG1 layer | Same as BG0 above. |
0x06008000 | 0x2000 | BGF0U | Font resource. |
0x0600a000 | 0x2000 | "BGF1U" | Extended character codes 0x100-0x1ff map to these. Used by the program editor for the line numbers. |
0x0600c000 | 0x2000 | BGF0 clone | Duplicate of BGF0, unused normally. |
0x0600e000 | 0x2000 | "BGF1" clone | Duplicate of "BGF1," unused normally. |
0x06010000 | 0x2000 | BGD0U | Normal BGD0 resource, only used for the code editor bg. |
0x06012000 | 0x2000 | BGD1U | Normal BGD1 resource, possibly entirely usused? This is normally accessible by PTC programs. |
0x06014000 | 0x2000 | "BGD2U" | "Normal" BGD2 resource, unused on top screen AFAIK and normally inaccessible. |
0x06016000 | 0x2000 | "BGD3U" | Same as "BGD2," normally inaccessible. |
0x06018000 | 0x2000 | BGU0U | Normal BGU resources, already accessible by PTC. |
0x0601a000 | 0x2000 | BGU1U | Normal. |
0x0601c000 | 0x2000 | BGU2U | Normal |
0x0601e000 | 0x2000 | BGU3U | Normal |
0x06200000 | 0x2000 | Lower screen text screen FG | This is the lower screen console text screen. Same properties as upper screen, used by the function keys as well as PNLSTR. |
0x06202000 | 0x2000 | Lower screen panel BG | Used for the panel graphics. |
0x06204000 | 0x2000 | Lower screen BG0 layer | It's the standard BG layer. Everything here can already be controlled from PTC, uses BGU resources. |
0x06206000 | 0x2000 | Lower screen BG1 layer | Same as BG0 above. |
0x06208000 | 0x2000 | BGF0L | Font resource. |
0x0620a000 | 0x2000 | "BGF1L" | Same as upper screen. |
0x0620c000 | 0x2000 | BGF0 clone | Duplicate of BGF0, unused normally. |
0x0620e000 | 0x2000 | "BGF1" clone | Duplicate of "BGF1," unused normally. |
0x06210000 | 0x2000 | BGD0L | Normal BGD0 resource, used for the panel BG screen. |
0x06212000 | 0x2000 | BGD1L | Normal BGD1 resource, used for the dialogs. Accessible normally. |
0x06214000 | 0x2000 | "BGD2L" | "Normal" BGD2 resource, normally inaccessible. Used for popup dialogs, maybe? Not clear yet. |
0x06216000 | 0x2000 | "BGD3L" | Same as "BGD2," normally inaccessible. |
0x06218000 | 0x2000 | BGU0 | Normal BGU resources, already accessible by PTC. |
0x0621a000 | 0x2000 | BGU1 | Normal. |
0x0621c000 | 0x2000 | BGU2 | Normal |
0x0621e000 | 0x2000 | BGU3 | Normal |
0x06400000 | 0x10000 | SPU | Upper screen sprites. Each bank is size 0x2000, and there are 8 banks. These are all normally accessible. |
0x06410000 | 0x4000 | SPSU | Upper screen SPS sprites. I think this is only used for the text cursor? This is accessible, but mostly unused. |
0x06414000 | 0xc000 | GRPU | Currently rendered GRP data for the upper screen. Format is exactly the same as GRP files and the GRP DU above - a 4x3 set of 8x8 characters of 8x8 pixels (8 bits) |
0x06600000 | 0x8000 | SPD | System icons. |
0x06608000 | 0x8000 | "SPK" | Keyboard and panel sprites. |
0x06610000 | 0x4000 | SPSL | Lower screen SPS sprites. These are accessible normally, but a few at the end are unused. It may be possible to set and use many more lower screen sprites, by defining more characters past the end and writing to OAM directly or something to get past PTC's limits. |
0x06614000 | 0xc000 | GRPL | Same as GRPU, but for the lower screen. |
VRAM banks[]
The banks used (useful to know if you want to change something without breaking the normal operations). Also check out this site which is a good way to visualize this information: https://mtheall.com/banks.html#A=MBG0&B=MOBJ0&C=SBG&D=SOBJ&F=BGEPAL01&G=OBJEPAL&H=SBGEPAL&I=SOBJEPAL
Note that banks A,B,C,D are all completely utilized. You can perform partial replacements with smaller banks for some, but you lose or break certain features. For example, replacing B with E as Main OBJ data loses the text cursor and the upper screen GRP pages, but SPU sprites can be used still if you call CHRINIT "SPU*"
first.
The extended OBJ palettes are definitely used for GRP data; it's not clear how the extended palettes are used for BG tiles yet, if at all.
Bank | Usage |
---|---|
A | Main BG |
B | Main OBJ (Sprites) |
C | Sub BG |
D | Sub OBJ (Sprites) |
E | Unused |
F | Main BG extended palette |
G | Main OBJ extended palette |
H | Sub BG extended palette |
I | Sub OBJ extended palette |
CHR code | Command |
---|---|
e000 | NEW |
e001 | LIST |
e002 | RUN |
e003 | CONT |
e004 | FILES |
e005 | IF |
e006 | THEN |
e007 | FOR |
e008 | TO |
e009 | STEP |
e00a | NEXT |
e00b | STOP |
e00c | END |
e00d | CLEAR |
e00e | REM |
e00f | ' |
e010 | LABEL |
e011 | @ |
e012 | GOTO |
e013 | GOSUB |
e014 | RETURN |
e015 | ON |
e016 | DIM |
e017 | TMREAD |
e018 | DTREAD |
e019 | DATA |
e01a | READ |
e01b | RESTORE |
e01c | KEY |
e01d | WAIT(初代で読み込むとVSYNC) |
e01e | CLS |
e01f | |
e020 | ? |
e021 | LOCATE |
e022 | INPUT |
e023 | LINPUT |
e024 | COLOR |
e025 | LOAD |
e026 | SAVE |
e027 | (null) |
e028 | SENDFILE |
e029 | RECVFILE |
e02a | DELETE |
e02b | RENAME |
e02c | VISIBLE |
e02d | COLINIT |
e02e | COLSET |
e02f | COLREAD |
e030 | CHRINIT |
e031 | CHRSET |
e032 | CHRREAD |
e033 | BGPAGE |
e034 | BGCLIP |
e035 | BGPUT |
e036 | SPPAGE |
e037 | SPSET |
e038 | SPCLR |
e039 | SPOFS |
e03a | SPSCALE |
e03b | SPANGLE |
e03c | GPAGE |
e03d | GCOLOR |
e03e | GPSET |
e03f | GPAINT |
e040 | GLINE |
e041 | GBOX |
e042 | GCIRCLE |
e043 | GPUTCHR |
e044 | GCLS |
e045 | PNLTYPE |
e046 | ICONSET |
e047 | ICONCLR |
e048 | (null) |
e049 | PNLSTR |
e04a | BEEP |
e04b | BGMPLAY |
e04c | BGMSTOP |
e04d | SPANIM |
e04e | BGOFS |
e04f | BGREAD |
e050 | (null) |
e051 | (null) |
e052 | SPCHR |
e053 | EXEC |
e054 | GFILL |
e055 | SPREAD |
e056 | SPHOME |
e057 | SPCOL |
e058 | REBOOT |
e059 | TALK |
e05a | TALKSTOP |
e05b | BGMSET |
e05c | BGMCLEAR |
e05d | BGMSETV |
e05e | SPSETV |
e05f | SWAP |
e060 | SORT |
e061 | RSORT |
e062 | SPCOLVEC |
e063 | ELSE |
e064 | BGCLR |
e065 | ACLS |
e066 | (null) |
e067 | BGCOPY |
e068 | GDRAWMD |
e069 | GPRIO |
e06a | GCOPY |
e06b | BGMSETD |
e06c | APPEND |
e06d | BGFILL |
e06e | (null) |
e06f | BGMPRG |
e070 | BGMVOL |
e071 | BREPEAT |
e072 | VSYNC |
e400 | ASC |
e401 | CHR$ |
e402 | VAL |
e403 | STR$ |
e404 | HEX$ |
e405 | MID$ |
e406 | LEN |
e407 | RND |
e408 | ABS |
e409 | SGN |
e40a | PI |
e40b | RAD |
e40c | SIN |
e40d | COS |
e40e | TAN |
e40f | ATAN |
e410 | SQR |
e411 | EXP |
e412 | LOG |
e413 | FLOOR |
e414 | BUTTON |
e415 | INKEY$ |
e416 | CHKCHR |
e417 | GSPOIT |
e418 | ICONCHK |
e419 | BGMCHK |
e41a | DEG |
e41b | SPCHK |
e41c | LEFT$ |
e41d | RIGHT$ |
e41e | POW |
e41f | SPHITSP |
e420 | TALKCHK |
e421 | BGMGETV |
e422 | SPGETV |
e423 | SPHITRC |
e424 | SUBST$ |
e425 | INSTR |
e426 | BGCHK |
e427 | SPHIT |
e428 | BTRIG |
e800 | TRUE |
e801 | FALSE |
e802 | CANCEL |
e803 | VERSION |
e804 | TCHX |
e805 | TCHY |
e806 | TCHST |
e807 | TCHTIME |
e808 | FUNCNO |
e809 | CSRX |
e80a | CSRY |
e80b | ERR |
e80c | ERL |
e80d | RESULT |
e80e | TIME$ |
e80f | DATE$ |
e810 | MAINCNTL |
e811 | MAINCNTH |
e812 | ICONPUSE |
e813 | ICONPAGE |
e814 | ICONPMAX |
e815 | FREEMEM |
e816 | FREEVAR |
e817 | MEM$ |
e818 | TABSTEP |
e819 | SYSBEEP |
e81a | SPHITX |
e81b | SPHITY |
e81c | SPHITT |
e81d | SPHITNO |
e81e | KEYBOARD |
e81f | PRGNAME$ |
e820 | PACKAGE$ |
ec00 | NOT |
ec01 | AND |
ec02 | OR |
ec03 | XOR |