(MESS) ti99_8: Included the Pascal ROM and made the Pascal subsystem

work at last. [Michael Zapf]
This commit is contained in:
Michael Zapf 2013-12-11 19:35:52 +00:00
parent 5f073e11ea
commit 5b4587f182
4 changed files with 172 additions and 77 deletions

View File

@ -981,6 +981,7 @@ static const mapper8_list_entry mapper_devices[] =
// Physical (need to pack this in here as well to keep config simple)
// but these lines will be put into a separate list
{ DRAMNAME, PHYSIC, STOP, 0x000000, 0xff0000, 0x000000 }, // 000000-00ffff 64 KiB DRAM
{ PCODENAME, PHYSIC, STOP, 0xf00000, 0xffc000, 0x000000 }, // f00000-f03fff P-Code ROM
{ MAINBOARD8_TAG, PHYSIC, CONT, 0xff4000, 0xffe000, 0x000000 }, // ff4000-ff5fff Internal DSR
{ GROMPORT_TAG, PHYSIC, STOP, 0xff6000, 0xffe000, 0x000000 }, // ff6000-ff7fff Cartridge ROM space
{ GROMPORT_TAG, PHYSIC, STOP, 0xff8000, 0xffe000, 0x000000 }, // ff8000-ff9fff Cartridge ROM space
@ -1139,6 +1140,16 @@ ROM_START(ti99_8)
ROM_REGION(0x8000, ROM1_TAG, 0)
ROM_LOAD("u25_rom1.bin", 0x0000, 0x8000, CRC(b574461a) SHA1(42c6aed44802cfabdd26b565d6e5ddfcd689f11e))
// Physical memory space (mapped): P-Code ROM
// This circuit is only available in later versions of the console and seems
// to be picky-backed on ROM1.
// To make things worse, the decoding logic of the custom chips do not show
// the required select line for this ROM on the available schematics, so
// they seem to be from the earlier version. The location in the address
// space was determined by ROM disassembly.
ROM_REGION(0x8000, PCODEROM_TAG, 0)
ROM_LOAD("u25a_pas.bin", 0x0000, 0x4000, CRC(d7ed6dd6) SHA1(32212ce6426ceccbff73d342d4a3ef699c0ae1e4))
// System GROMs. 3 chips @ f830
// The schematics do not enumerate the circuits but only talk about
// "circuits on board" (COB) so we name the GROMs as gM_N.bin where M is the

View File

@ -14,6 +14,10 @@
Note: The TI-99/8's internal codename was "Armadillo"
==============================
Mapper (codename "Amigo")
==============================
Initial setting of mapper (as defined in the power-up routine, TI-99/4A mode)
0 00ff0000 -> Unmapped; logical address 0000...0fff = ROM0
@ -33,94 +37,160 @@
E 00006800 -> DRAM; e000 = 006800, efff = 0077ff
F 00007800 -> DRAM; f000 = 007800, ffff = 0087ff
Informations taken from
[1] ARMADILLO PRODUCT SPECIFICATIONS
[2] TI-99/8 Graphics Programming Language interpreter
Format of map table entry (not emulated)
* bit 0: WTPROT: page is write protected if 1
* bit 1: XPROT: page is execute protected if 1
* bit 2: RDPROT: page is read protected if 1
* bit 3: reserved, value is ignored
* bits 4-7: reserved, always forced to 0
* bits 8-23: page base address in 24-bit virtual address space
+------+------+------+------+---+---+---+---------+----------+---------+
| WProt| XProt| RProt| * | 0 | 0 | 0 | Upper | High | Low |
+------+------+------+------+---+---+---+---------+----------+---------+
Format of mapper control register:
* bit 0-4: unused???
* bit 5-6: map file to load/save (0 for file 0, 1 for file 1, etc.)
* bit 7: 0 -> load map file from RAM, 1 -> save map file to RAM
WProt: Write protection if set to 1
XProt: Execute protection if set to 1
RProt: Read protection if set to 1
Format of mapper status register (cleared by read):
* bit 0: WPE - Write-Protect Error
* bit 1: XCE - eXeCute Error
* bit 2: RPE - Read-Protect Error
* bits 3-7: unused???
When a protection violation occurs, the tms9901 INT1* pin is pulled low
(active). The pin remains low until the mapper status register is read.
Memory error interrupts are enabled by setting WTPROT/XPROT/RDPROT. When
an error occurs, the tms9901 INT1* pin is pulled low (active). The pin
remains low until the mapper status register is read.
Address handling
----------------
Physical address is (Upper * 2^16) + (High * 2^8) + Low
24-bit address map:
* >000000->00ffff: console RAM
* >010000->feffff: expansion?
* >ff0000->ff0fff: empty???
* >ff1000->ff3fff: unused???
* >ff4000->ff5fff: DSR space
* >ff6000->ff7fff: cartridge space
* >ff8000->ff9fff(???): >4000 ROM (normally enabled with a write to CRU >2700)
* >ffa000->ffbfff(?): >2000 ROM
* >ffc000->ffdfff(?): >6000 ROM
The mapper calculates the actual physical address by looking up the
table entry from the first four bits of the logical address and then
*adding* the remaining 12 bits of the logical address on the map value.
The value 0xff0000 is used to indicate a non-mapped area.
Mapper control register
-----------------------
The mapper control register is used to initiate a map load/save operation.
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | Map File | RW|
+---+---+---+---+---+---+---+---+
The map file is a number from 0-7 indicating the set of map values for the
operation, which means the location in SRAM where the next 64 values are
loaded from or stored into.
RW = 1: load from SRAM into mapper
RW = 0: store from mapper into SRAM
When read, the mapper register returns the violation flags:
+------+------+------+---+---+---+---+---+
| WProt| XProt| RProt| 0 | 0 | 0 | 0 | 0 |
+------+------+------+---+---+---+---+---+
Logical address space (LAS)
===========================
The LAS is the address space as seen by the TMS 9995 CPU. It is 64 KiB large.
The LAS can be configured in two ways:
- the native (99/8) mode
- and the compatibility mode (99/4A)
Both modes are selected by CRU bit 20 on base 0000 (named "CRUS").
The console starts up in compatibility mode.
The compatibility mode organizes the LAS in a similar way as the TI-99/4A.
This means that machine language programs should run with no or only minor
changes. In particular, game cartridges work without problems.
The native mode rearranges the address space and puts memory-mapped devices
to other positions.
TI-99/4A compatibility mode (CRUS=1)
------------------------------------
0000-1fff: 2 KiB ROM0
2000-7fff: Free area
8000-87ff: 2 KiB SRAM
8000-81ff: mapper files (8 files with 16*4 bytes each)
8200-82ff: Free RAM
8300-83ff: Scratch-pad RAM as in the 99/4A
8400-840f: Sound chip
8800-880f: VDP read port (data, status)
8810-881f: Mapper access port
8820-8bff: Free area
8c00-8c0f: VDP write port (data, address)
8c10-8fff: Free area
9000-900f: Speech synthesizer read (on-board)
9010-93ff: Free area
9400-940f: Speech synthesizer write (on-board)
9410-97ff: Free area
9800-980f: System GROM read (data, address)
9810-9bff: Free area
9c00-9c0f: System GROM write (data, address)
9c10-fffb: Free area
fffc-ffff: NMI vector
TI-99/8 native mode (CRUS=0)
----------------------------
0000-efff: Free area
f000-f7ff: 2 KiB SRAM
f000-f1ff: mapper files (8 files with 16*4 bytes each)
f200-f7ff: Free RAM
f800-f80f: Sound chip
f810-f81f: VDP read (data, status) and write (data, address)
f820-f82f: Speech synthesizer read/write
f830-f83f: System GROM read/write
f840-f86f: Free area
f870-f87f: Mapper access port
f880-fffb: Free area
fffc-ffff: NMI vector
Note that ROM0 is not visible in the native mode.
If CRU bit 21 (PTGEN*) is set to 0, Pascal GROMs appear in the LAS in either
mode. It is highly recommended to use native mode when turning on these
GROMs, because the area where they appear may be occupied by a program in
99/4A mode.
Pascal and Text-to-speech GROM enabled (PTGEN*=0)
-------------------------------------------------
f840-f84f: Text-to-speech GROM read/write
f850-f85f: P-Code library #1 GROM read/write
f860-f86f: P-Code library #2 GROM read/write
Physical address space (PAS)
============================
The PAS is 24 bits wide and accessed via the custom mapper chip nicknamed
"Amigo". The mapper exchanges map definitions with SRAM (see LAS). That
means, a map can be prepared in SRAM, and for activating it, the mapper
is accessed on its port, telling it to load or save a map.
000000-00ffff: 64 KiB console DRAM
010000-efffff: undefined
f00000-f03fff: P-Code ROM (not mentioned in [1])
f04000-feffff: undefined
ff0000 : unmapped (code for mapper)
ff0001-ff3fff: undefined
ff4000-ff5fff: DSR ROM in Peripheral Box, Hexbus DSR (CRU 1700) or additional ROM (CRU 2700)
ff6000-ff9fff: Cartridge ROM space
ffa000-ffdfff: 16 KiB ROM1
ffe000-ffe00f: Interrupt level sense
ffe010-ffffff: undefined
CRU map:
Since the tms9995 supports full 15-bit CRU addresses, the >1000->17ff
(>2000->2fff) range was assigned to support up to 16 extra expansion slot.
The good thing with using >1000->17ff is the fact that older expansion
cards that only decode 12 address bits will think that addresses
>1000->17ff refer to internal TI99 peripherals (>000->7ff range), which
suppresses any risk of bus contention.
* >0000->001f (>0000->003e): tms9901
- P4: 1 -> MMD (Memory Mapped Devices?) at >8000, ROM enabled
- P5: 1 -> no P-CODE GROMs
* >0800->17ff (>1000->2ffe): Peripheral CRU space
* >1380->13ff (>2700->27fe): Internal DSR, with two output bits:
- >2700: Internal DSR select (parts of Basic and various utilities)
- >2702: SBO -> hardware reset
CRU map (I/O address space)
===========================
0000-003e: TMS9901 system interface (see ti99_8.c)
1700-17fe: Hexbus
2000-26fe: Future external devices
2700-27fe: Additional ROM ("internal DSR")
2702: System reset (when set to 1)
2800-3ffe: Future external devices
4000-fffe: Future external devices
Memory map (TMS9901 P4 == 1):
When TMS9901 P4 output is set, locations >8000->9fff are ignored by mapper.
* >8000->83ff: SRAM (>8000->80ff is used by the mapper DMA controller
to hold four map files) (r/w)
* >8400: sound port (w)
* >8410->87ff: SRAM (r/w)
* >8800: VDP data read port (r)
* >8802: VDP status read port (r)
* >8810: memory mapper status and control registers (r/w)
* >8c00: VDP data write port (w)
* >8c02: VDP address and register write port (w)
* >9000: speech synthesizer read port (r)
* >9400: speech synthesizer write port (w)
* >9800 GPL data read port (r)
* >9802 GPL address read port (r)
* >9c00 GPL data write port -- unused (w)
* >9c02 GPL address write port (w)
Memory map (TMS9901 P5 == 0):
When TMS9901 P5 output is cleared, locations >f840->f8ff(?) are ignored by
mapper.
* >f840: data port for P-code grom library 0 (r?)
* >f850: data port for P-code grom library 1 (r?)
* >f860: data port for P-code grom library 2 (r?)
* >f842: address port for P-code grom library 0 (r/w?)
* >f852: address port for P-code grom library 1 (r/w?)
* >f862: address port for P-code grom library 2 (r/w?)
The TMS9995 offers the full 15-bit CRU address space. Devices designed for
the TI-99/4A should only be accessed in the area 1000-1ffe. They will (by
design) incompletely decode the CRU address and be mirrored in the higher areas.
Michael Zapf, October 2010
February 2012: Rewritten as class
Informations taken from
[1] ARMADILLO PRODUCT SPECIFICATIONS
[2] TI-99/8 Graphics Programming Language interpreter
***************************************************************************/
#include "mapper8.h"
@ -524,6 +594,10 @@ void mainboard8_device::access_physical_r( address_space& space, offs_t pas_addr
*value = m_rom1[0x2000 | (pas_address & 0x1fff)];
if (TRACE_MEM) LOG("mainboard_998: (ROM) %06x -> %02x\n", pas_address, *value);
break;
case MAP8_PCODE:
*value = m_pcode[pas_address & 0x3fff];
if (TRACE_MEM) LOG("mainboard_998: (PCDOE) %06x -> %02x\n", pas_address, *value);
break;
case MAP8_INTS:
// Interrupt sense
LOG("mainboard_998: ILSENSE not implemented.\n");
@ -562,6 +636,9 @@ void mainboard8_device::access_physical_w( address_space& space, offs_t pas_addr
case MAP8_ROM1C0:
if (TRACE_MEM) LOG("mainboard_998: (ROM1) %06x <- %02x (ignored)\n", pas_address, data);
break;
case MAP8_PCODE:
if (TRACE_MEM) LOG("mainboard_998: (PCODE) %06x <- %02x (ignored)\n", pas_address, data);
break;
case MAP8_INTS:
// Interrupt sense
LOG("ti99_8: write to ilsense ignored\n");
@ -609,7 +686,7 @@ void mainboard8_device::device_start()
LOG("ti99_8: Starting mapper\n");
// String values of the pseudo constants, used in the configuration.
const char *const pseudodev[6] = { SRAMNAME, ROM0NAME, ROM1A0NAME, ROM1C0NAME, DRAMNAME, INTSNAME };
const char *const pseudodev[7] = { SRAMNAME, ROM0NAME, ROM1A0NAME, ROM1C0NAME, DRAMNAME, PCODENAME, INTSNAME };
const mapper8_config *conf = reinterpret_cast<const mapper8_config *>(static_config());
@ -620,6 +697,7 @@ void mainboard8_device::device_start()
m_dram = machine().root_device().memregion(DRAM_TAG)->base();
m_rom0 = machine().root_device().memregion(ROM0_TAG)->base();
m_rom1 = machine().root_device().memregion(ROM1_TAG)->base();
m_pcode = machine().root_device().memregion(PCODEROM_TAG)->base();
// Clear the lists
m_logcomp.reset();
@ -641,7 +719,7 @@ void mainboard8_device::device_start()
device_t *dev = NULL;
mapper8_device_kind kind = MAP8_UNDEF;
for (int j=1; (j < 7) && (kind == MAP8_UNDEF); j++)
for (int j=1; (j < 8) && (kind == MAP8_UNDEF); j++)
{
// Pseudo devices are enumerated as 1 ... 6 (see MAP8_SRAM etc.)
if (strcmp(entry[i].name, pseudodev[j-1])==0) kind = (mapper8_device_kind)j;

View File

@ -37,6 +37,7 @@ extern const device_type OSO;
#define ROM1C0NAME "ROM1C"
#define INTSNAME "INTS"
#define DRAMNAME "DRAM"
#define PCODENAME "PCODE"
#define SRAM_SIZE 2048
#define DRAM_SIZE 65536
@ -50,6 +51,7 @@ enum mapper8_device_kind
MAP8_ROM1A0,
MAP8_ROM1C0,
MAP8_DRAM,
MAP8_PCODE,
MAP8_INTS,
MAP8_DEV // device by name
};
@ -206,6 +208,9 @@ private:
// ROM area of the system. Directly connected to the physical address decoder.
UINT8 *m_rom1;
// P-Code ROM area of the system. Directly connected to the physical address decoder.
UINT8 *m_pcode;
// Custom chips
required_device<ti998_oso_device> m_oso;
};

View File

@ -42,6 +42,7 @@
#define SPEECH_TAG "speech"
#define ROM0_TAG "rom0"
#define ROM1_TAG "rom1"
#define PCODEROM_TAG "pcode"
// Geneve
#define GKEYBOARD_TAG "gkeyboard"