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
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 |
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.
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 |
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 |