Internal Memory Maps

This memory map is incomplete. Updates and corrections are gratefully accepted. Last modify 6 July 2014.

Some portions of this are thanks to "Jay's Factory" (see his PyutaDev site for lots of great technical data in Japanese), and a lot of it is due to James Host, the man of Tomy Tutor's desiring (apologies to J. S. Bach). Raphael Nabet also contributed a number of tidbits from his work on a Tomy Tutor MESS driver.

Why three memory maps? Because the 9995 and 9918 see different tracts of memory, and BASIC and GRAPHIC mode have completely different layouts. In the unexpanded Tomy (which means any Tomy you'll run across), everything is stored in the 16K VDP RAM, which the 9995 has no direct access to except through the 9918's I/O ports. Because of this, the 9918's VDP memory map is much more important and useful than the 9995, unless we added more memory into the 9995's address space.

Back to Programming The Tomy Tutor | Back to the main page


What the 9995 sees

Raphael Nabet gets credit for the vast majority of this table.

I've fudged a little here and put CRU addresses in this unified map. Unless otherwise noted, addresses are for *CPU* space.



                   *** $0000-$7FFF is the 32K BIOS ***
 it is also possible to replace the BIOS with an external ROM (see $E000 range)

0000                            
                                reset vector (level 0)
                                0000-0001: WP   0002-0003: PC (%)
0004
                                level 1 and 2 IRQ vectors (%)
                                idem. These just seem to reset the system.
000C
                                additional vectors
0040
                                XOP vectors (%)
				The BIOS doesn't seem to use these for XOPs.
				Instead, this is a branch table.
0080
				BIOS code
				(CRU only: $1EE0-FE: 9995 flag register;
					$1FDA: MID flag)
4000
				GBASIC
				(on the American v2.3 firmware, the GPL
					interpreter and VDP RAMLUT co-exist
					with GBASIC in this range)

              *** $8000-$BFFF is the 16K option ROM area ***

8000
				BASIC (Tutor only) and/or cartridge ROM
					(controlled by $E100)
				To be recognized, a cartridge must have a
				$55, $66 or $aa header sequence.

                         *** end ROM ***
C000
				unmapped (possible use in 24K cartridges)
E000
				I/O range
				---------
				9918A VDP data/register ports: $E000, E002
				"MMU" banking controls: $E100-E1FF
					$E100 write: enable cartridge, disable
						BIOS at $0000 (???) -- magic
						required at $E110 for this
					$E108 write: enable BASIC ROM, disable
						cartridge at $8000
					$E10C write: enable cartridge, disable
						BASIC ROM at $8000
					$E110 must be $42 to enable $E100
						and to replace the BIOS with
						an installed cartridge ROM.
						BLWP assumed at $0000 (??).
				SN76489AN sound data port: $E200
				Device handshaking: $E600
					Unknown purpose, disk drive maybe?
				Printer handshaking: $E800
				This is a standard Centronics port.
					$E810 write: parallel data bus
					$E820 read: parallel port busy
					$E840 write: port handshake output
				Keyboard lines: $EC00-$EC7E (*CRU*)
					(CRU physical address $7600-$763F)
				Cassette lines: $ED00-$EEFF
					$ED00 (*CRU*): input level
						(physical address $7680)
					$EE00 write: tape output zero
					$EE20 write: tape output one
					$EE40 write: tape IRQ on
					$EE60 write: tape IRQ off
					$EE80, A0, C0, E0: ???
					
F000
                                TMS9995 RAM (*)
F0FC
                                ??
FFFA
                                decrementer (*)
FFFC
                                NMI vector (*)
FFFF

Asterisked locations are provided internally by the 9995 (either on-chip RAM or on-chip mmapped I/O [the decrementer]). (%) indicates vectors provided by the "BIOS" ROM.

Vectors consist of two 16-bit words, the new workspace pointer and the new program counter. This allows very seamless context switching. See the Hardware page for more information.

What the 9918 sees: BASIC

Mostly thanks to James Host's work, the Tomy guru.

The 9995 sees the VDP in its memory space at $E000/2 and communicates with it byte-by-byte through these two ports to manipulate registers and RAM. Multiple successive accesses to RAM are handled by built-in VDP RAM pointer incrementation, which speeds sequential reads and writes. Other than its scratchpad RAM, the 9995 has no "chip" RAM of its own, so it must access all other resources through the VDP.

However, knowing this doesn't help us at all in Tomy BASIC. Since we have no way of manipulating those ports directly, just how can you get into this memory? SCELL and MCELL (see the BASIC keywords page) ostensibly manipulate video memory, but since all memory is video memory and that memory is shared between various tasks, their use can be stolen for more subversive means. MCELL, nominally used for custom characters, is supposed to only operate on "characters 128-159" (examination of the memory locations it actually uses shows that it's really character glyphs 224-255) but has no bounds checking and so actually can operate on any range of them. MCELL's minor limitation is that you can only store whole octets at once, while the major one is that you can't write beyond VDP $0800.

SCELL, however, is the real deal, since it can be coerced into writing anywhere in the 16K range. SCELL's official task is directly placing one or more character(s) at an arbitrary screen location, and obviously, you can write anywhere in screen memory you like. However, by pointing SCELL at the very last screen location, and then having it paint more than one character, you can cause it to bleed out into the rest of VDP memory because it does not bounds-check either (example: SCELL(24,32,byte,how many characters past $0300)). Just do it in reverse (highest location first) to store a particular sequence. Of course, SCELL will overwrite any locations in between, so be careful out there.



		** MCELL or SCELL can access this memory **

0000                            
                                screen memory
				OR
				start of character set (MCELL "character 160")
				OR
				sprite bitmaps
0300
                                MCELL "character 0" (really #96)
				OR
				sprite attribute table, x32, in sets of:
					(y coord, x coord, colour,
					 bitmap offset)
				(James: BASIC work area in MCELL "14-15")
0380
				MCELL "character 16" (really #112)
				(James: cursor on at "30", border at "31",
					BASIC work area at "20-21")
0700
				start of legally "MCELL-able" characters
					(really #224, not MCELL "128")
0788
				BASIC work areas (input buffer at MCELL
					"232-251")

		** SCELL must be used beyond this point **

0800
				colour bytes (fore/back for each octet), x32
0820
				BASIC program space, subdivided (10,208 bytes)
					* first, line numbers, line links
					* next, actual program text
					* next, floating point storage
					* next, string storage
					* stack (at $2FFF, going back, min
						size 512 bytes?)
3000
				cassette input area
3100
				apparently unused
3FFF

What the 9918 sees: GRAPHIC

Analysis of the Tomy GRAPHIC tape format shows that the Tutor mostly dumps VDP memory in place when saving to tape. The Tutor does do some moving around prior to writing out to tape, so precise byte-by-byte analysis is probably not possible with a mere tape dump, but armed with our understanding of the 9918ANL and knowing that the Tutor places the 9918ANL in Mode 2 for hi-res display we can make solid large-scale guesses about how memory is laid out in this mode (confirmed by the very useful VDP debugging feature in TutorEm).

GBASIC, unfortunately, does not have the same quirks we can abuse in BASIC. CELL can at least grab any of the hi-res cells, and we can do limited modification of their colour octets at least with string variables (see GBASIC and MONitor Keywords for an explanation), but no other portions of memory can be changed programmatically: sprites cannot be modified other than moving them, and no other portions of memory, including the GBASIC program text itself, can be directly accessed.


0000                            

                                pattern generator table, 6144 bytes

1800

				sprite data, 128 bytes

1880

				work area (sprite description table?)

1C00

				pattern name table, 768 bytes

1F00

				work area (sprite description table?)

2000

				colour octets, 6144 bytes

3800

				GBASIC text

3F90

				work area/unused?

3FFF


Back to Programming The Tomy Tutor | Back to the main page