(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) // Physical (need to pack this in here as well to keep config simple)
// but these lines will be put into a separate list // but these lines will be put into a separate list
{ DRAMNAME, PHYSIC, STOP, 0x000000, 0xff0000, 0x000000 }, // 000000-00ffff 64 KiB DRAM { 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 { 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, 0xff6000, 0xffe000, 0x000000 }, // ff6000-ff7fff Cartridge ROM space
{ GROMPORT_TAG, PHYSIC, STOP, 0xff8000, 0xffe000, 0x000000 }, // ff8000-ff9fff 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_REGION(0x8000, ROM1_TAG, 0)
ROM_LOAD("u25_rom1.bin", 0x0000, 0x8000, CRC(b574461a) SHA1(42c6aed44802cfabdd26b565d6e5ddfcd689f11e)) 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 // System GROMs. 3 chips @ f830
// The schematics do not enumerate the circuits but only talk about // 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 // "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" 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) Initial setting of mapper (as defined in the power-up routine, TI-99/4A mode)
0 00ff0000 -> Unmapped; logical address 0000...0fff = ROM0 0 00ff0000 -> Unmapped; logical address 0000...0fff = ROM0
@ -33,94 +37,160 @@
E 00006800 -> DRAM; e000 = 006800, efff = 0077ff E 00006800 -> DRAM; e000 = 006800, efff = 0077ff
F 00007800 -> DRAM; f000 = 007800, ffff = 0087ff 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) 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 | WProt| XProt| RProt| * | 0 | 0 | 0 | Upper | High | Low |
* 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
Format of mapper control register: WProt: Write protection if set to 1
* bit 0-4: unused??? XProt: Execute protection if set to 1
* bit 5-6: map file to load/save (0 for file 0, 1 for file 1, etc.) RProt: Read protection if set to 1
* bit 7: 0 -> load map file from RAM, 1 -> save map file to RAM
Format of mapper status register (cleared by read): When a protection violation occurs, the tms9901 INT1* pin is pulled low
* bit 0: WPE - Write-Protect Error (active). The pin remains low until the mapper status register is read.
* bit 1: XCE - eXeCute Error
* bit 2: RPE - Read-Protect Error
* bits 3-7: unused???
Memory error interrupts are enabled by setting WTPROT/XPROT/RDPROT. When Address handling
an error occurs, the tms9901 INT1* pin is pulled low (active). The pin ----------------
remains low until the mapper status register is read. Physical address is (Upper * 2^16) + (High * 2^8) + Low
24-bit address map: The mapper calculates the actual physical address by looking up the
* >000000->00ffff: console RAM table entry from the first four bits of the logical address and then
* >010000->feffff: expansion? *adding* the remaining 12 bits of the logical address on the map value.
* >ff0000->ff0fff: empty???
* >ff1000->ff3fff: unused??? The value 0xff0000 is used to indicate a non-mapped area.
* >ff4000->ff5fff: DSR space
* >ff6000->ff7fff: cartridge space Mapper control register
* >ff8000->ff9fff(???): >4000 ROM (normally enabled with a write to CRU >2700) -----------------------
* >ffa000->ffbfff(?): >2000 ROM The mapper control register is used to initiate a map load/save operation.
* >ffc000->ffdfff(?): >6000 ROM
+---+---+---+---+---+---+---+---+
| 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: CRU map (I/O address space)
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. 0000-003e: TMS9901 system interface (see ti99_8.c)
The good thing with using >1000->17ff is the fact that older expansion 1700-17fe: Hexbus
cards that only decode 12 address bits will think that addresses 2000-26fe: Future external devices
>1000->17ff refer to internal TI99 peripherals (>000->7ff range), which 2700-27fe: Additional ROM ("internal DSR")
suppresses any risk of bus contention. 2702: System reset (when set to 1)
* >0000->001f (>0000->003e): tms9901 2800-3ffe: Future external devices
- P4: 1 -> MMD (Memory Mapped Devices?) at >8000, ROM enabled 4000-fffe: Future external devices
- 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
The TMS9995 offers the full 15-bit CRU address space. Devices designed for
Memory map (TMS9901 P4 == 1): the TI-99/4A should only be accessed in the area 1000-1ffe. They will (by
When TMS9901 P4 output is set, locations >8000->9fff are ignored by mapper. design) incompletely decode the CRU address and be mirrored in the higher areas.
* >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?)
Michael Zapf, October 2010 Michael Zapf, October 2010
February 2012: Rewritten as class February 2012: Rewritten as class
Informations taken from
[1] ARMADILLO PRODUCT SPECIFICATIONS
[2] TI-99/8 Graphics Programming Language interpreter
***************************************************************************/ ***************************************************************************/
#include "mapper8.h" #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)]; *value = m_rom1[0x2000 | (pas_address & 0x1fff)];
if (TRACE_MEM) LOG("mainboard_998: (ROM) %06x -> %02x\n", pas_address, *value); if (TRACE_MEM) LOG("mainboard_998: (ROM) %06x -> %02x\n", pas_address, *value);
break; 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: case MAP8_INTS:
// Interrupt sense // Interrupt sense
LOG("mainboard_998: ILSENSE not implemented.\n"); 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: case MAP8_ROM1C0:
if (TRACE_MEM) LOG("mainboard_998: (ROM1) %06x <- %02x (ignored)\n", pas_address, data); if (TRACE_MEM) LOG("mainboard_998: (ROM1) %06x <- %02x (ignored)\n", pas_address, data);
break; break;
case MAP8_PCODE:
if (TRACE_MEM) LOG("mainboard_998: (PCODE) %06x <- %02x (ignored)\n", pas_address, data);
break;
case MAP8_INTS: case MAP8_INTS:
// Interrupt sense // Interrupt sense
LOG("ti99_8: write to ilsense ignored\n"); LOG("ti99_8: write to ilsense ignored\n");
@ -609,7 +686,7 @@ void mainboard8_device::device_start()
LOG("ti99_8: Starting mapper\n"); LOG("ti99_8: Starting mapper\n");
// String values of the pseudo constants, used in the configuration. // 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()); 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_dram = machine().root_device().memregion(DRAM_TAG)->base();
m_rom0 = machine().root_device().memregion(ROM0_TAG)->base(); m_rom0 = machine().root_device().memregion(ROM0_TAG)->base();
m_rom1 = machine().root_device().memregion(ROM1_TAG)->base(); m_rom1 = machine().root_device().memregion(ROM1_TAG)->base();
m_pcode = machine().root_device().memregion(PCODEROM_TAG)->base();
// Clear the lists // Clear the lists
m_logcomp.reset(); m_logcomp.reset();
@ -641,7 +719,7 @@ void mainboard8_device::device_start()
device_t *dev = NULL; device_t *dev = NULL;
mapper8_device_kind kind = MAP8_UNDEF; 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.) // 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; 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 ROM1C0NAME "ROM1C"
#define INTSNAME "INTS" #define INTSNAME "INTS"
#define DRAMNAME "DRAM" #define DRAMNAME "DRAM"
#define PCODENAME "PCODE"
#define SRAM_SIZE 2048 #define SRAM_SIZE 2048
#define DRAM_SIZE 65536 #define DRAM_SIZE 65536
@ -50,6 +51,7 @@ enum mapper8_device_kind
MAP8_ROM1A0, MAP8_ROM1A0,
MAP8_ROM1C0, MAP8_ROM1C0,
MAP8_DRAM, MAP8_DRAM,
MAP8_PCODE,
MAP8_INTS, MAP8_INTS,
MAP8_DEV // device by name MAP8_DEV // device by name
}; };
@ -206,6 +208,9 @@ private:
// ROM area of the system. Directly connected to the physical address decoder. // ROM area of the system. Directly connected to the physical address decoder.
UINT8 *m_rom1; UINT8 *m_rom1;
// P-Code ROM area of the system. Directly connected to the physical address decoder.
UINT8 *m_pcode;
// Custom chips // Custom chips
required_device<ti998_oso_device> m_oso; required_device<ti998_oso_device> m_oso;
}; };

View File

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