Previous 199869 Revisions Next

r26231 Sunday 17th November, 2013 at 16:46:29 UTC by Michael Zapf
(MESS) ti99_8: Using a consistent, new ROM dump; partly rewritten [Michael Zapf]
[src/mess/drivers]ti99_8.c
[src/mess/machine/ti99]mapper8.c mapper8.h ti99defs.h

trunk/src/mess/machine/ti99/ti99defs.h
r26230r26231
3838#define SRAM_TAG        "sram8"
3939#define DRAM_TAG        "dram8"
4040#define MAPPER_TAG      "mapper"
41#define MAINBOARD8_TAG  "mainboard8"
4142#define SPEECH_TAG      "speech"
43#define ROM0_TAG        "rom0"
44#define ROM1_TAG        "rom1"
4245
4346// Geneve
4447#define GKEYBOARD_TAG   "gkeyboard"
trunk/src/mess/machine/ti99/mapper8.c
r26230r26231
22// copyright-holders:Michael Zapf
33/***************************************************************************
44
5    TI-99/8 Address decoder and mapper
5    TI-99/8 main board logic
66
77    This component implements the address decoder and mapper logic from the
88    TI-99/8 console.
r26230r26231
3737    [1] ARMADILLO PRODUCT SPECIFICATIONS
3838    [2] TI-99/8 Graphics Programming Language interpreter
3939
40    Format of map table entry (not emulated)
41
42    * bit 0: WTPROT: page is write protected if 1
43    * bit 1: XPROT: page is execute protected if 1
44    * bit 2: RDPROT: page is read protected if 1
45    * bit 3: reserved, value is ignored
46    * bits 4-7: reserved, always forced to 0
47    * bits 8-23: page base address in 24-bit virtual address space
48
49    Format of mapper control register:
50    * bit 0-4: unused???
51    * bit 5-6: map file to load/save (0 for file 0, 1 for file 1, etc.)
52    * bit 7: 0 -> load map file from RAM, 1 -> save map file to RAM
53
54    Format of mapper status register (cleared by read):
55    * bit 0: WPE - Write-Protect Error
56    * bit 1: XCE - eXeCute Error
57    * bit 2: RPE - Read-Protect Error
58    * bits 3-7: unused???
59
60    Memory error interrupts are enabled by setting WTPROT/XPROT/RDPROT.  When
61    an error occurs, the tms9901 INT1* pin is pulled low (active).  The pin
62    remains low until the mapper status register is read.
63
6424-bit address map:
65    * >000000->00ffff: console RAM
66    * >010000->feffff: expansion?
67    * >ff0000->ff0fff: empty???
68    * >ff1000->ff3fff: unused???
69    * >ff4000->ff5fff: DSR space
70    * >ff6000->ff7fff: cartridge space
71    * >ff8000->ff9fff(???): >4000 ROM (normally enabled with a write to CRU >2700)
72    * >ffa000->ffbfff(?): >2000 ROM
73    * >ffc000->ffdfff(?): >6000 ROM
74
75
76CRU map:
77    Since the tms9995 supports full 15-bit CRU addresses, the >1000->17ff
78    (>2000->2fff) range was assigned to support up to 16 extra expansion slot.
79    The good thing with using >1000->17ff is the fact that older expansion
80    cards that only decode 12 address bits will think that addresses
81    >1000->17ff refer to internal TI99 peripherals (>000->7ff range), which
82    suppresses any risk of bus contention.
83    * >0000->001f (>0000->003e): tms9901
84      - P4: 1 -> MMD (Memory Mapped Devices?) at >8000, ROM enabled
85      - P5: 1 -> no P-CODE GROMs
86    * >0800->17ff (>1000->2ffe): Peripheral CRU space
87    * >1380->13ff (>2700->27fe): Internal DSR, with two output bits:
88      - >2700: Internal DSR select (parts of Basic and various utilities)
89      - >2702: SBO -> hardware reset
90
91
92Memory map (TMS9901 P4 == 1):
93    When TMS9901 P4 output is set, locations >8000->9fff are ignored by mapper.
94    * >8000->83ff: SRAM (>8000->80ff is used by the mapper DMA controller
95      to hold four map files) (r/w)
96    * >8400: sound port (w)
97    * >8410->87ff: SRAM (r/w)
98    * >8800: VDP data read port (r)
99    * >8802: VDP status read port (r)
100    * >8810: memory mapper status and control registers (r/w)
101    * >8c00: VDP data write port (w)
102    * >8c02: VDP address and register write port (w)
103    * >9000: speech synthesizer read port (r)
104    * >9400: speech synthesizer write port (w)
105    * >9800 GPL data read port (r)
106    * >9802 GPL address read port (r)
107    * >9c00 GPL data write port -- unused (w)
108    * >9c02 GPL address write port (w)
109
110
111Memory map (TMS9901 P5 == 0):
112    When TMS9901 P5 output is cleared, locations >f840->f8ff(?) are ignored by
113    mapper.
114    * >f840: data port for P-code grom library 0 (r?)
115    * >f850: data port for P-code grom library 1 (r?)
116    * >f860: data port for P-code grom library 2 (r?)
117    * >f842: address port for P-code grom library 0 (r/w?)
118    * >f852: address port for P-code grom library 1 (r/w?)
119    * >f862: address port for P-code grom library 2 (r/w?)
120
40121    Michael Zapf, October 2010
41122    February 2012: Rewritten as class
42123
r26230r26231
44125
45126#include "mapper8.h"
46127
47#define VERBOSE 1
128#define TRACE_CRU 0
129#define TRACE_MEM 0
130#define TRACE_MAP 0
131#define TRACE_CONFIG 0
132
48133#define LOG logerror
49134
50ti998_mapper_device::ti998_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
51: bus8z_device(mconfig, MAPPER8, "TI-99/8 Memory mapper", tag, owner, clock, "ti99_mapper8", __FILE__)
52{
53}
135mainboard8_device::mainboard8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
136   : bus8z_device(mconfig, MAINBOARD8, "TI-99/8 Main board", tag, owner, clock, "ti998_mainboard", __FILE__),
137   m_oso(*this, OSO_TAG)
138   { }
54139
55140/***************************************************************************
56141    CRU access
r26230r26231
59144#define HEXBUS_CRU_BASE 0x1700
60145#define MAPPER_CRU_BASE 0x2700
61146
62READ8Z_MEMBER(ti998_mapper_device::crureadz)
147READ8Z_MEMBER(mainboard8_device::crureadz)
63148{
64   if (VERBOSE>8) LOG("mapper8: read CRU %04x ignored\n", offset);
149   if (TRACE_CRU) LOG("mainboard_998: read CRU %04x ignored\n", offset);
65150   // Nothing here.
66151}
67152
r26230r26231
69154    CRU handling. We handle the internal device at CRU address 0x2700 via
70155    this mapper component.
71156*/
72WRITE8_MEMBER(ti998_mapper_device::cruwrite)
157WRITE8_MEMBER(mainboard8_device::cruwrite)
73158{
74159   if ((offset & 0xff00)==MAPPER_CRU_BASE)
75160   {
r26230r26231
79164      case 0:
80165         // Turn on/off the internal DSR
81166         m_dsr_selected = (data!=0);
82         if (VERBOSE>7) LOG("mapper8: DSR select = %d\n", data);
167         if (TRACE_CRU) LOG("mainboard_998: DSR select = %d\n", data);
83168         break;
84169      case 1:
85         if (VERBOSE>2) LOG("mapper8: System reset by CRU request\n");
170         if (TRACE_CRU) LOG("mainboard_998: System reset by CRU request\n");
86171         machine().schedule_soft_reset();
87172         break;
88173      }
r26230r26231
91176
92177   if ((offset & 0xff00)==HEXBUS_CRU_BASE)
93178   {
94      if (VERBOSE>5) LOG("mapper8: Set CRU>%04x (Hexbus) to %d\n",offset,data);
179      int bit = (offset & 0xff)>>1;
180      switch (bit)
181      {
182      case 0:
183         // Turn on/off the Hexbus DSR
184         m_hexbus_selected = (data!=0);
185         if (TRACE_CRU) LOG("mainboard_998: Hexbus select = %d\n", data);
186         break;
187      default:
188         if (TRACE_CRU) LOG("mainboard_998: Set CRU>%04x (Hexbus) to %d\n",offset,data);
189         break;
190      }
95191      return;
96192   }
97193
98194   if ((offset & 0xff00)>=0x0100)
99195   {
100      if (VERBOSE>5) LOG("mapper8: Set CRU>%04x (unknown) to %d\n",offset,data);
196      if (TRACE_CRU) LOG("mainboard_998: Set CRU>%04x (unknown) to %d\n",offset,data);
101197      return;
102198   }
103199}
104200
105void ti998_mapper_device::CRUS_set(bool state)
201void mainboard8_device::CRUS_set(bool state)
106202{
107   if (VERBOSE>7) LOG("mapper8: set CRUS=%d\n", state);
203   if (TRACE_CRU) LOG("mainboard_998: set CRUS=%d\n", state);
108204   m_CRUS = state;
109205}
110206
111207/*
112208    Note that PTGEN is negative logic. We invert these semantics here.
113209*/
114void ti998_mapper_device::PTGE_set(bool state)
210void mainboard8_device::PTGE_set(bool state)
115211{
116   if (VERBOSE>7) LOG("mapper8: set PTGEN=%d\n", state? 1:0);
212   if (TRACE_CRU) LOG("mainboard_998: set PTGEN=%d\n", state? 1:0);
117213   m_PTGE = state;
118214}
119215
r26230r26231
124220/*
125221    This method is called via the address map.
126222*/
127READ8_MEMBER( ti998_mapper_device::readm )
223READ8_MEMBER( mainboard8_device::readm )
128224{
129225   UINT8 value = 0;
130226   bool found = false;
131   if (VERBOSE>5) LOG("mapper8: read from %04x\n", offset);
227   if (TRACE_MEM) LOG("mainboard_998: read from %04x\n", offset);
132228   found = access_logical_r(space, offset, &value, mem_mask);
133229   m_waitcount = 2;
134230
r26230r26231
153249   return value;
154250}
155251
156WRITE8_MEMBER( ti998_mapper_device::writem )
252WRITE8_MEMBER( mainboard8_device::writem )
157253{
158254   bool found = false;
159255
r26230r26231
189285    8810 (TI99EM): mapper: ignore
190286    ff4000 (PHYSIC): DSR
191287*/
192READ8Z_MEMBER( ti998_mapper_device::readz )
288READ8Z_MEMBER( mainboard8_device::readz )
193289{
194290   if ((offset & 0xffe000)==0xff4000)
195291   {
196292      if (m_dsr_selected)
197293      {
198294         //  Starts at 0x4000 in the image
199         *value = m_rom[0x4000 | (offset & 0x1fff)];
200         if (VERBOSE>7) LOG("mapper8: (DSR)  %04x -> %02x\n", offset, *value);
295         *value = m_rom1[0x4000 | (offset & 0x1fff)];
296         if (TRACE_MEM) LOG("mainboard_998: (intDSR)  %04x -> %02x\n", offset, *value);
201297      }
298      else
299      {
300         if (m_hexbus_selected)
301         {
302            if ((offset & 0x1ff0)==0x1ff0)
303            {
304               *value = m_oso->read(space, (offset>>1) & 0x0003);
305            }
306            else
307            {
308               //  Starts at 0x6000 in the image
309               *value = m_rom1[0x6000 | (offset & 0x1fff)];
310               if (TRACE_MEM) LOG("mainboard_998: (HexDSR)  %04x -> %02x\n", offset, *value);
311            }
312         }
313      }
202314   }
203315   else
204316   {
205317      if (((offset & 0xfff0)==0xf870 && m_CRUS==false)||(((offset & 0xfff0)==0x8810 && m_CRUS==true)))
206318      {
207         if (VERBOSE>4) LOG("mapper8: read access to mapper ignored: %04x\n", offset);
319         if (TRACE_MEM) LOG("mainboard_998: read access to mapper ignored: %04x\n", offset);
208320      }
209321   }
210322}
r26230r26231
214326    ff4000 (PHYSIC): DSR. ignore
215327
216328*/
217WRITE8_MEMBER( ti998_mapper_device::write )
329WRITE8_MEMBER( mainboard8_device::write )
218330{
219331   if ((offset & 0xffe000)==0xff4000)
220332   {
221      if (VERBOSE>4) LOG("mapper8: Write access to DSR space %06x ignored\n", offset);
333      if (m_hexbus_selected)
334      {
335         if ((offset & 0x1ff0)==0x1ff0)
336         {
337            m_oso->write(space, (offset>>1) & 0x0003, data);
338         }
339         else
340         {
341            LOG("mainboard_998: Write access to Hexbus DSR address %06x ignored\n", offset);
342         }
343      }
344      else
345      {
346         if (m_dsr_selected)
347         {
348            LOG("mainboard_998: Write access to internal DSR address %06x ignored\n", offset);
349         }
350         else
351         {
352            LOG("mainboard_998: Write access to unmapped DSR space at address %06x ignored\n", offset);
353         }
354      }
222355   }
223356   else
224357   {
r26230r26231
234367    SRAM into the mapper and vice versa.
235368    Format:
236369    0000 bbbl; bbb=bank, l=load
370
371    TODO: Emulate properly, making use of HOLD
237372*/
238void ti998_mapper_device::mapwrite(int offset, UINT8 data)
373void mainboard8_device::mapwrite(int offset, UINT8 data)
239374{
240375   if ((data & 0xf0)==0x00)
241376   {
242377      int bankindx = (data & 0x0e)>>1;
243378      if (data & 1)
244379      {
245         if (VERBOSE>7) LOG("mapper8: load mapper from SRAM, bank %d\n", bankindx);
380         if (TRACE_MAP) LOG("mainboard_998: load mapper from SRAM, bank %d\n", bankindx);
246381         // Load from SRAM
247382         // In reality the CPU is put on HOLD during this transfer
248383         for (int i=0; i < 16; i++)
r26230r26231
250385            int ptr = (bankindx << 6);
251386            m_pas_offset[i] =   (m_sram[(i<<2) + ptr] << 24) | (m_sram[(i<<2)+ ptr+1] << 16)
252387            | (m_sram[(i<<2) + ptr+2] << 8) | (m_sram[(i<<2) + ptr+3]);
253            if (VERBOSE>7) LOG("mapper8: load %d=%08x\n", i, m_pas_offset[i]);
388            if (TRACE_MAP) LOG("mainboard_998: load %d=%08x\n", i, m_pas_offset[i]);
254389         }
255390      }
256391      else
257392      {
258         if (VERBOSE>7) LOG("mapper8: store mapper to SRAM, bank %d\n", bankindx);
393         if (TRACE_MAP) LOG("mainboard_998: store mapper to SRAM, bank %d\n", bankindx);
259394         // Store in SRAM
260395         for (int i=0; i < 16; i++)
261396         {
r26230r26231
264399            m_sram[(i<<2) + ptr +1] =  (m_pas_offset[i] >> 16)& 0xff;
265400            m_sram[(i<<2) + ptr +2] =  (m_pas_offset[i] >> 8)& 0xff;
266401            m_sram[(i<<2) + ptr +3] =  (m_pas_offset[i])& 0xff;
267            if (VERBOSE>7) LOG("mapper8: save %d=%08x\n", i, m_pas_offset[i]);
402            if (TRACE_MAP) LOG("mainboard_998: save %d=%08x\n", i, m_pas_offset[i]);
268403         }
269404      }
270405   }
r26230r26231
274409    Lookup methods.
275410***************************************************************************/
276411
277bool ti998_mapper_device::access_logical_r(address_space& space, offs_t offset, UINT8 *value, UINT8 mem_mask )
412bool mainboard8_device::access_logical_r(address_space& space, offs_t offset, UINT8 *value, UINT8 mem_mask )
278413{
279414   bool found = false;
280415   logically_addressed_device *ldev = m_logcomp.first();
281416   bus8z_device *bdev = NULL;
282417
283   if (VERBOSE>8) LOG("mapper8: offset=%04x; CRUS=%d, PTGEN=%d\n", offset, m_CRUS? 1:0, m_PTGE? 0:1);
418   if (TRACE_MEM) LOG("mainboard_998: offset=%04x; CRUS=%d, PTGEN=%d\n", offset, m_CRUS? 1:0, m_PTGE? 0:1);
284419   while (ldev != NULL)
285420   {
286      if (VERBOSE>5) LOG("mapper8: checking node=%s\n", ldev->m_config->name);
421      if (TRACE_MEM) LOG("mainboard_998: checking node=%s\n", ldev->m_config->name);
287422      // Check the mode
288423      if (((ldev->m_config->mode == NATIVE) && (m_CRUS==false))
289424         || ((ldev->m_config->mode == TI99EM) && (m_CRUS==true))
r26230r26231
295430            {
296431            case MAP8_SRAM:
297432               *value = m_sram[offset & ~ldev->m_config->address_mask];
298               if (VERBOSE>7) LOG("mapper8: (SRAM) %04x -> %02x\n", offset, *value);
433               if (TRACE_MEM) LOG("mainboard_998: (SRAM) %04x -> %02x\n", offset, *value);
299434               break;
300435            case MAP8_ROM0:
301436               // Starts at 0000
302               *value = m_rom[offset & ~ldev->m_config->address_mask];
303               if (VERBOSE>7) LOG("mapper8: (ROM)  %04x -> %02x\n", offset, *value);
437               *value = m_rom0[offset & ~ldev->m_config->address_mask];
438               if (TRACE_MEM) LOG("mainboard_998: (ROM0)  %04x -> %02x\n", offset, *value);
304439               break;
305440            case MAP8_DEV:
306441               // device
307442               bdev = static_cast<bus8z_device*>(ldev->m_device);
308443               bdev->readz(space, offset, value, mem_mask);
309               if (VERBOSE>7) LOG("mapper8: (dev %s)  %04x -> %02x\n", ldev->m_config->name, offset, *value);
444               if (TRACE_MEM) LOG("mainboard_998: (dev %s)  %04x -> %02x\n", ldev->m_config->name, offset, *value);
310445               break;
311446            default:
312               if (VERBOSE>1) LOG("mapper8: Invalid kind for read access: %d\n", ldev->m_kind);
447               if (TRACE_MEM) LOG("mainboard_998: Invalid kind for read access: %d\n", ldev->m_kind);
313448            }
314449            found = true;
315450            if (ldev->m_config->stop==STOP) break;
r26230r26231
320455   return found;
321456}
322457
323bool ti998_mapper_device::access_logical_w(address_space& space, offs_t offset, UINT8 data, UINT8 mem_mask )
458bool mainboard8_device::access_logical_w(address_space& space, offs_t offset, UINT8 data, UINT8 mem_mask )
324459{
325460   bool found = false;
326461   logically_addressed_device *ldev = m_logcomp.first();
r26230r26231
339474            {
340475            case MAP8_SRAM:
341476               m_sram[offset & ~ldev->m_config->address_mask] = data;
342               if (VERBOSE>7) LOG("mapper8: (SRAM) %04x <- %02x\n", offset, data);
477               if (TRACE_MEM) LOG("mainboard_998: (SRAM) %04x <- %02x\n", offset, data);
343478               break;
344479            case MAP8_ROM0:
345               if (VERBOSE>7) LOG("mapper8: (ROM)  %04x <- %02x (ignored)\n", offset, data);
480               if (TRACE_MEM) LOG("mainboard_998: (ROM0)  %04x <- %02x (ignored)\n", offset, data);
346481               break;
347482            case MAP8_DEV:
348483               // device
349484               bdev = static_cast<bus8z_device*>(ldev->m_device);
350485               bdev->write(space, offset, data, mem_mask);
351               if (VERBOSE>7) LOG("mapper8: (dev %s)  %04x <- %02x\n", ldev->m_config->name, offset, data);
486               if (TRACE_MEM) LOG("mainboard_998: (dev %s)  %04x <- %02x\n", ldev->m_config->name, offset, data);
352487               break;
353488            default:
354               if (VERBOSE>1) LOG("mapper8: Invalid kind for write access: %d\n", ldev->m_kind);
489               if (TRACE_MEM) LOG("mainboard_998: Invalid kind for write access: %d\n", ldev->m_kind);
355490            }
356491            found = true;
357492            if (ldev->m_config->stop==STOP) break;
r26230r26231
363498}
364499
365500
366void ti998_mapper_device::access_physical_r( address_space& space, offs_t pas_address, UINT8 *value, UINT8 mem_mask )
501void mainboard8_device::access_physical_r( address_space& space, offs_t pas_address, UINT8 *value, UINT8 mem_mask )
367502{
368503   physically_addressed_device *pdev = m_physcomp.first();
369504   bus8z_device *bdev = NULL;
r26230r26231
376511         {
377512         case MAP8_DRAM:
378513            *value = m_dram[pas_address & ~pdev->m_config->address_mask];
379            if (VERBOSE>3) LOG("mapper8: (DRAM) %06x -> %02x\n", pas_address, *value);
514            if (TRACE_MEM) LOG("mainboard_998: (DRAM) %06x -> %02x\n", pas_address, *value);
380515            break;
381         case MAP8_ROM1:
516         case MAP8_ROM1A0:
517            // Starts at 0000 in the image, 8K
518            *value = m_rom1[pas_address & 0x1fff];
519            if (TRACE_MEM) LOG("mainboard_998: (ROM) %06x -> %02x\n", pas_address, *value);
520            break;
521         case MAP8_ROM1C0:
382522            // Starts at 2000 in the image, 8K
383            *value = m_rom[0x2000 | (pas_address & 0x1fff)];
384            if (VERBOSE>3) LOG("mapper8: (ROM) %06x -> %02x\n", pas_address, *value);
523            *value = m_rom1[0x2000 | (pas_address & 0x1fff)];
524            if (TRACE_MEM) LOG("mainboard_998: (ROM)  %06x -> %02x\n", pas_address, *value);
385525            break;
386         case MAP8_ROM1A:
387            // Starts at 6000 in the image, 8K
388            *value = m_rom[0x6000 | (pas_address & 0x1fff)];
389            if (VERBOSE>3) LOG("mapper8: (ROM)  %06x -> %02x\n", pas_address, *value);
390            break;
391526         case MAP8_INTS:
392527            // Interrupt sense
393            if (VERBOSE>1) LOG("ti99_8: ILSENSE not implemented.\n");
528            LOG("mainboard_998: ILSENSE not implemented.\n");
394529            break;
395530         case MAP8_DEV:
396531            // devices
397532            bdev = static_cast<bus8z_device*>(pdev->m_device);
398533            bdev->readz(space, pas_address, value, mem_mask);
399            if (VERBOSE>7) LOG("mapper8: (dev %s)  %06x -> %02x\n", pdev->m_config->name, pas_address, *value);
534            if (TRACE_MEM) LOG("mainboard_998: (dev %s)  %06x -> %02x\n", pdev->m_config->name, pas_address, *value);
400535            break;
401536         default:
402            if (VERBOSE>1) LOG("mapper8: Invalid kind for physical read access: %d\n", pdev->m_kind);
537            LOG("mainboard_998: Invalid kind for physical read access: %d\n", pdev->m_kind);
403538         }
404539         if (pdev->m_config->stop==STOP) break;
405540      }
r26230r26231
407542   }
408543}
409544
410void ti998_mapper_device::access_physical_w( address_space& space, offs_t pas_address, UINT8 data, UINT8 mem_mask )
545void mainboard8_device::access_physical_w( address_space& space, offs_t pas_address, UINT8 data, UINT8 mem_mask )
411546{
412547   physically_addressed_device *pdev = m_physcomp.first();
413548   bus8z_device *bdev = NULL;
r26230r26231
420555         {
421556         case MAP8_DRAM:
422557            m_dram[pas_address & ~pdev->m_config->address_mask] = data;
423            if (VERBOSE>3) LOG("mapper8: (DRAM) %06x <- %02x\n", pas_address, data);
558            if (TRACE_MEM) LOG("mainboard_998: (DRAM) %06x <- %02x\n", pas_address, data);
424559            break;
425         case MAP8_ROM1:
426         case MAP8_ROM1A:
427            if (VERBOSE>7) LOG("mapper8: (ROM)  %06x <- %02x (ignored)\n", pas_address, data);
560         case MAP8_ROM1A0:
561         case MAP8_ROM1C0:
562            if (TRACE_MEM) LOG("mainboard_998: (ROM1)  %06x <- %02x (ignored)\n", pas_address, data);
428563            break;
429564         case MAP8_INTS:
430565            // Interrupt sense
431            if (VERBOSE>1) LOG("ti99_8: write to ilsense ignored\n");
566            LOG("ti99_8: write to ilsense ignored\n");
432567            break;
433568         case MAP8_DEV:
434569            // devices
435570            bdev = static_cast<bus8z_device*>(pdev->m_device);
436            if (VERBOSE>7) LOG("mapper8: (dev %s)  %06x <- %02x\n", pdev->m_config->name, pas_address, data);
571            if (TRACE_MEM) LOG("mainboard_998: (dev %s)  %06x <- %02x\n", pdev->m_config->name, pas_address, data);
437572            bdev->write(space, pas_address, data, mem_mask);
438573            break;
439574         default:
440            if (VERBOSE>1) LOG("mapper8: Invalid kind for physical write access: %d\n", pdev->m_kind);
575            LOG("mainboard_998: Invalid kind for physical write access: %d\n", pdev->m_kind);
441576         }
442577         if (pdev->m_config->stop==STOP) break;
443578      }
r26230r26231
449584    The mapper is connected to the clock line in order to operate
450585    the wait state counter.
451586*/
452void ti998_mapper_device::clock_in(int clock)
587void mainboard8_device::clock_in(int clock)
453588{
454589   if (clock==ASSERT_LINE && m_waitcount!=0)
455590   {
r26230r26231
468603
469604    Note that device_reset is too late; the initial context switch occurs earlier.
470605*/
471void ti998_mapper_device::device_start()
606void mainboard8_device::device_start()
472607{
473   if (VERBOSE>5) LOG("ti99_8: Starting mapper\n");
608   LOG("ti99_8: Starting mapper\n");
474609
475610   // String values of the pseudo constants, used in the configuration.
476   const char *const pseudodev[6] = { SRAMNAME, ROM0NAME, ROM1NAME, ROM1ANAME, DRAMNAME, INTSNAME };
611   const char *const pseudodev[6] = { SRAMNAME, ROM0NAME, ROM1A0NAME, ROM1C0NAME, DRAMNAME, INTSNAME };
477612
478613   const mapper8_config *conf = reinterpret_cast<const mapper8_config *>(static_config());
479614
r26230r26231
482617
483618   m_sram = machine().root_device().memregion(SRAM_TAG)->base();
484619   m_dram = machine().root_device().memregion(DRAM_TAG)->base();
485   m_rom  = machine().root_device().memregion("maincpu")->base();
620   m_rom0  = machine().root_device().memregion(ROM0_TAG)->base();
621   m_rom1  = machine().root_device().memregion(ROM1_TAG)->base();
486622
487623   // Clear the lists
488624   m_logcomp.reset();
r26230r26231
521657               {
522658                  logically_addressed_device *ad = new logically_addressed_device(kind, (device_t*)dev, entry[i]);
523659                  m_logcomp.append(*ad);
524                  if (VERBOSE>6) LOG("mapper8: Device %s mounted into logical address space.\n", entry[i].name);
660                  if (TRACE_CONFIG) LOG("mainboard_998: Device %s mounted into logical address space.\n", entry[i].name);
525661               }
526662               else
527663               {
528664                  physically_addressed_device *ad = new physically_addressed_device(kind, (device_t*)dev, entry[i]);
529665                  m_physcomp.append(*ad);
530                  if (VERBOSE>6) LOG("mapper8: Device %s mounted into physical address space.\n", entry[i].name);
666                  if (TRACE_CONFIG) LOG("mainboard_998: Device %s mounted into physical address space.\n", entry[i].name);
531667               }
532668            }
533669            else
534670            {
535               if (VERBOSE>1) LOG("mapper8: Device %s not found.\n", entry[i].name);
671               if (TRACE_CONFIG) LOG("mainboard_998: Device %s not found.\n", entry[i].name);
536672            }
537673         }
538674      }
539675   }
540   if (VERBOSE>4) LOG("Mapper logical device count = %d\n", m_logcomp.count());
541   if (VERBOSE>4) LOG("Mapper physical device count = %d\n", m_physcomp.count());
676   if (TRACE_CONFIG) LOG("Mapper logical device count = %d\n", m_logcomp.count());
677   if (TRACE_CONFIG) LOG("Mapper physical device count = %d\n", m_physcomp.count());
542678
543679   m_dsr_selected = false;
544680   m_CRUS = true;
r26230r26231
548684   for (int i=0; i < 16; i++) m_pas_offset[i] = 0;
549685}
550686
551void ti998_mapper_device::device_reset()
687void mainboard8_device::device_reset()
552688{
553689   m_dsr_selected = false;
554690   m_CRUS = true;
r26230r26231
561697   m_ready(ASSERT_LINE);
562698}
563699
564const device_type MAPPER8 = &device_creator<ti998_mapper_device>;
700MACHINE_CONFIG_FRAGMENT( ti998_mainboard )
701   MCFG_DEVICE_ADD(OSO_TAG, OSO, 0)
702MACHINE_CONFIG_END
703
704machine_config_constructor mainboard8_device::device_mconfig_additions() const
705{
706   return MACHINE_CONFIG_NAME( ti998_mainboard );
707}
708
709const device_type MAINBOARD8 = &device_creator<mainboard8_device>;
710
711/***************************************************************************
712
713  Custom chips of the TI-99/8
714  OSO: Hexbus interface
715
716****************************************************************************/
717
718enum
719{
720   HSKWT = 0x80
721};
722
723ti998_oso_device::ti998_oso_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
724: device_t(mconfig, OSO, "OSO Hexbus interface", tag, owner, clock, "ti998_oso", __FILE__)
725{
726   LOG("ti998/oso: Creating OSO\n");
727}
728
729READ8_MEMBER( ti998_oso_device::read )
730{
731   int value = 0;
732   offset &= 0x03;
733   LOG("ti998/oso: OSO chip read access %04x -> %02x\n", (offset<<1) | 0x5ff0, value);
734   switch (offset)
735   {
736   case 0:
737      // read 5FF8: read data register
738      break;
739   case 1:
740      // read 5FFA: read status register
741      // We return handshake_write=1 to prevent lock-ups (until the hexbus is properly implemented)
742      value = HSKWT;
743      break;
744   case 2:
745      // read 5FFC: read control register
746      break;
747   case 3:
748      // read 5FFE: read transmit register
749      break;
750   }
751
752   return value;
753}
754
755WRITE8_MEMBER( ti998_oso_device::write )
756{
757   offset &= 0x03;
758   LOG("ti998/oso: OSO chip write access %04x <- %02x\n", (offset<<1) | 0x5ff0, data);
759}
760
761void ti998_oso_device::device_start()
762{
763}
764
765const device_type OSO = &device_creator<ti998_oso_device>;
trunk/src/mess/machine/ti99/mapper8.h
r26230r26231
1919#include "peribox.h"
2020#include "ti99defs.h"
2121
22extern const device_type MAPPER8;
22extern const device_type MAINBOARD8;
23extern const device_type OSO;
2324
25#define OSO_TAG "oso"
26
2427#define NATIVE 0
2528#define TI99EM 1
2629#define PATGEN 2
r26230r26231
3033
3134#define SRAMNAME "SRAM"
3235#define ROM0NAME "ROM0"
33#define ROM1NAME "ROM1"
34#define ROM1ANAME "ROM1A"
36#define ROM1A0NAME "ROM1A"
37#define ROM1C0NAME "ROM1C"
3538#define INTSNAME "INTS"
3639#define DRAMNAME "DRAM"
3740
3841#define SRAM_SIZE 2048
3942#define DRAM_SIZE 65536
4043
41// Pseudo devices which are not implemented by a proper device. We use these
42// constants in the read/write functions.
44// We use these constants in the read/write functions.
4345enum mapper8_device_kind
4446{
4547   MAP8_UNDEF = 0,
4648   MAP8_SRAM,
4749   MAP8_ROM0,
48   MAP8_ROM1,
49   MAP8_ROM1A,
50   MAP8_ROM1A0,
51   MAP8_ROM1C0,
5052   MAP8_DRAM,
5153   MAP8_INTS,
5254   MAP8_DEV        // device by name
r26230r26231
7779class logically_addressed_device
7880{
7981   friend class simple_list<logically_addressed_device>;
80   friend class ti998_mapper_device;
82   friend class mainboard8_device;
8183
8284public:
8385   logically_addressed_device(mapper8_device_kind kind, device_t *busdevice, const mapper8_list_entry &entry)
r26230r26231
9698class physically_addressed_device
9799{
98100   friend class simple_list<physically_addressed_device>;
99   friend class ti998_mapper_device;
101   friend class mainboard8_device;
100102
101103public:
102104   physically_addressed_device(mapper8_device_kind kind, device_t *busdevice, const mapper8_list_entry &entry)
r26230r26231
110112};
111113
112114/*
115    Custom chip: OSO
116*/
117class ti998_oso_device : public device_t
118{
119public:
120   ti998_oso_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
121   DECLARE_READ8_MEMBER( read );
122   DECLARE_WRITE8_MEMBER( write );
123   void device_start();
124};
125
126
127/*
113128    Main class
114129*/
115class ti998_mapper_device : public bus8z_device
130class mainboard8_device : public bus8z_device
116131{
117132public:
118   ti998_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
133   mainboard8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
119134   DECLARE_READ8_MEMBER( readm);       // used from address map
120135   DECLARE_WRITE8_MEMBER( writem );    // used from address map
121136
r26230r26231
131146   void clock_in(int state);
132147
133148protected:
134   virtual void device_start(void);
135   virtual void device_reset(void);
149   void device_start(void);
150   void device_reset(void);
151   machine_config_constructor device_mconfig_additions() const;
136152
137153private:
138154   bool access_logical_r(address_space& space, offs_t offset, UINT8 *value, UINT8 mem_mask );
r26230r26231
153169   // Select bit for the internal DSR.
154170   bool    m_dsr_selected;
155171
172   // Select bit for the Hexbus DSR.
173   bool    m_hexbus_selected;
174
156175   // 99/4A compatibility mode. Name is taken from the spec. If 1, 99/4A compatibility is active.
157176   bool    m_CRUS;
158177
r26230r26231
175194   // DRAM area of the system. Connected to the mapped address bus.
176195   UINT8   *m_dram;
177196
178   // ROM area of the system. Directly connected to the address decoder.
179   UINT8   *m_rom;
197   // ROM area of the system. Directly connected to the logical address decoder.
198   UINT8   *m_rom0;
199
200   // ROM area of the system. Directly connected to the physical address decoder.
201   UINT8   *m_rom1;
202
203   // Custom chips
204   required_device<ti998_oso_device> m_oso;
180205};
181206
182207
183#define MCFG_MAPPER8_ADD(_tag, _devices)            \
184   MCFG_DEVICE_ADD(_tag, MAPPER8, 0) \
208#define MCFG_MAINBOARD8_ADD(_tag, _devices)            \
209   MCFG_DEVICE_ADD(_tag, MAINBOARD8, 0) \
185210   MCFG_DEVICE_CONFIG( _devices )
186211
187212#endif
trunk/src/mess/drivers/ti99_8.c
r26230r26231
55    The MESS TI-99/8 emulation driver
66
77    The TI-99/8 was the envisaged successor to the TI-99/4A but never passed
8    its prototype state. Only a few consoles were built. The ROMs were not
9    even finalized, so the few available consoles may have different
10    operating system versions.
8    its prototype state. Only a few dozens of consoles were built. The ROMs
9    were not even finalized, so the few available consoles have different
10    operating system versions and capabilities.
1111
12    There is some preliminary info:
1312
14Name: Texas Instruments Computer TI-99/8 (no "Home")
13    Characteristics
14    ---------------
1515
16References:
17    * machine room <http://...>
18    * TI99/8 user manual
19    * TI99/8 schematics
20    * TI99/8 ROM source code
21    * Message on TI99 yahoo group for CPU info
16    Name: "Texas Instruments Computer TI-99/8" (no "Home")
2217
23General:
24    * a few dozen units were built in 1983, never released
25    * CPU is a custom variant of tms9995 (part code MP9537): the 16-bit RAM and
26      (presumably) the on-chip decrementer are disabled
27    * 220kb(?) of ROM, including monitor, GPL interpreter, TI-extended basic
28      II, and a P-code interpreter with a few utilities.  More specifically:
29      - 32kb system ROM with GPL interpreter, TI-extended basic II and a few
30        utilities (no dump, but 90% of source code is available and has been
31        compiled)
32      - 18kb system GROMs, with monitor and TI-extended basic II (no dump,
33        but source code is available and has been compiled)
34      - 4(???)kb DSR ROM for hexbus (no dump)
18    Inofficial nickname: "Armadillo"
3519
36      32 KiB speech ROM: Contents are the same as used in the TI-99/4A speech
37         synthesizer, although the speech chip is slightly newer (MZ: verified
38         on a real system 07-2013)
20    CPU: Single-CPU system using a TMS9995, but as a variant named MP9537. This
21         variant does not offer on-chip RAM or decrementer.
3922
40      - 12(???)kb ROM with PCode interpreter (no dump)
41      - 2(3???)*48kb of GROMs with PCode data files (no dump)
42    * 2kb SRAM (16 bytes of which are hidden), 64kb DRAM (expandable to almost
43      16MBytes), 16kb vdp RAM
44    * tms9118 vdp (similar to tms9918a, slightly different bus interface and
45      timings)
46    * I/O
47      - 50-key keyboard, plus 2 optional joysticks
48      - sound and speech (both ti99/4(a)-like)
49      - Hex-Bus
50      - Cassette
51    * cartridge port on the top
52    * 50-pin(?) expansion port on the back
53    * Programs can enable/disable the ROM and memory mapped register areas.
23    Video: TMS9118 Video Display Processor with 16 KiB RAM. The 9118 has the
24         same capabilities as the 9918/28 in the TI-99/4A, except for the
25         missing GROM clock (which must be provided separately) and the
26         different DRAM type (2 chips TMS 4416 16K*4). Delivers a 60 Hz
27         interrupt to the CPU via the PSI.
5428
55Mapper:
56    Mapper has 4kb page size (-> 16 pages per map file), 32 bits per page
57    entry.  Address bits A0-A3 are the page index, whereas bits A4-A15 are the
58    offset in the page.  Physical address space is 16Mbytes.  All pages are 4
59    kBytes in length, and they can start anywhere in the 24-bit physical
60    address space.  The mapper can load any of 4 map files from SRAM by DMA.
61    Map file 0 is used by BIOS, file 1 by memory XOPs(?), file 2 by P-code
62    interpreter(???).
29    Keyboard: 50-key keyboard, slightly different to the TI-99/4A, but also with
30         modifiers Control, Function, Shift, Caps Lock. Connects to the TMS 9901
31         PSI like in the TI-99/4A, but the pin assignment and key matrix
32         are different:
33         - P0-P3: column select
34         - INT6*-INT11*: row inputs (INT6* is only used for joystick fire)
6335
64    Format of map table entry:
65    * bit 0: WTPROT: page is write protected if 1
66    * bit 1: XPROT: page is execute protected if 1
67    * bit 2: RDPROT: page is read protected if 1
68    * bit 3: reserved, value is ignored
69    * bits 4-7: reserved, always forced to 0
70    * bits 8-23: page base address in 24-bit virtual address space
36    Cassette: Identical to TI-99/4A, except that the CS2 unit is not implemented
7137
72    Format of mapper control register:
73    * bit 0-4: unused???
74    * bit 5-6: map file to load/save (0 for file 0, 1 for file 1, etc.)
75    * bit 7: 0 -> load map file from RAM, 1 -> save map file to RAM
38    Sound: SN94624 as used in the TI-99/4A
7639
77    Format of mapper status register (cleared by read):
78    * bit 0: WPE - Write-Protect Error
79    * bit 1: XCE - eXeCute Error
80    * bit 2: RPE - Read-Protect Error
81    * bits 3-7: unused???
40    Speech: TMS5200C, a rare variant of the TMS52xx family. Compatible to the
41         speech data for the separate speech synthesizer for the TI-99/4A.
42         Speech ROMs CD2325A, CD2326A (total 128K*1)
8243
83    Memory error interrupts are enabled by setting WTPROT/XPROT/RDPROT.  When
84    an error occurs, the tms9901 INT1* pin is pulled low (active).  The pin
85    remains low until the mapper status register is read.
44    ROM: TMS4764 (8K*8), called "ROM0" in the specifications [1]
45         TMS47256 (32K*8), called "ROM1" [1]
46         TMS47128 (16K*8), "P-Code ROM" (only available in late prototypes)
47         See below for contents
8648
8724-bit address map:
88    * >000000->00ffff: console RAM
89    * >010000->feffff: expansion?
90    * >ff0000->ff0fff: empty???
91    * >ff1000->ff3fff: unused???
92    * >ff4000->ff5fff: DSR space
93    * >ff6000->ff7fff: cartridge space
94    * >ff8000->ff9fff(???): >4000 ROM (normally enabled with a write to CRU >2700)
95    * >ffa000->ffbfff(?): >2000 ROM
96    * >ffc000->ffdfff(?): >6000 ROM
49    GROMs: TI-specific ROM circuits with internal address counter and 6 KiB
50         capacity (see grom.c)
51         3 GROMs (system GROMs, access via port at logical address F830)
52         8 GROMs (Pascal / Text-to-speech GROMs, port at logical address F840)
53         8 GROMs (Pascal GROMs, port at logical address F850)
54         3 GROMs (Pascal GROMs, access via port at logical address F860)
55         (total of 132 KiB GROM)
9756
57    RAM: 1 TMS4016 (SRAM 2K*8)
58         8 TMS4164 (DRAM 64K*1)
9859
99CRU map:
100    Since the tms9995 supports full 15-bit CRU addresses, the >1000->17ff
101    (>2000->2fff) range was assigned to support up to 16 extra expansion slot.
102    The good thing with using >1000->17ff is the fact that older expansion
103    cards that only decode 12 address bits will think that addresses
104    >1000->17ff refer to internal TI99 peripherals (>000->7ff range), which
105    suppresses any risk of bus contention.
106    * >0000->001f (>0000->003e): tms9901
107      - P4: 1 -> MMD (Memory Mapped Devices?) at >8000, ROM enabled
108      - P5: 1 -> no P-CODE GROMs
109    * >0800->17ff (>1000->2ffe): Peripheral CRU space
110    * >1380->13ff (>2700->27fe): Internal DSR, with two output bits:
111      - >2700: Internal DSR select (parts of Basic and various utilities)
112      - >2702: SBO -> hardware reset
60    PSI: (programmable system interface) TMS9901 with connections to
61         keyboard, joystick port, cassette port, and external interrupt lines
62         (video, peripheral devices)
11363
64    External connectors:
65         - Joystick port (compatible to TI-99/4A joystick slot)
66         - Cassette port
67         - Cartridge port (compatible to TI-99/4A cartridge slot, but vertically
68           orientated, so cartridges are plugged in from the top)
69         - I/O port (not compatible to TI-99/4A I/O port, needs a special P-Box
70           card called "Armadillo interface")
71         - Hexbus port (new peripheral system, also seen with later TI designs)
72         - Video port (composite)
11473
115Memory map (TMS9901 P4 == 1):
116    When TMS9901 P4 output is set, locations >8000->9fff are ignored by mapper.
117    * >8000->83ff: SRAM (>8000->80ff is used by the mapper DMA controller
118      to hold four map files) (r/w)
119    * >8400: sound port (w)
120    * >8410->87ff: SRAM (r/w)
121    * >8800: VDP data read port (r)
122    * >8802: VDP status read port (r)
123    * >8810: memory mapper status and control registers (r/w)
124    * >8c00: VDP data write port (w)
125    * >8c02: VDP address and register write port (w)
126    * >9000: speech synthesizer read port (r)
127    * >9400: speech synthesizer write port (w)
128    * >9800 GPL data read port (r)
129    * >9802 GPL address read port (r)
130    * >9c00 GPL data write port -- unused (w)
131    * >9c02 GPL address write port (w)
74    Custom chips: Five custom chips contain mapping and selection logic
75         - "Vaquerro": Logical address space decoder
76         - "Mofetta" : Physical address space decoder
77         - "Amigo"   : Mapper
78         - "Pollo"   : DRAM controller
79         - "Oso"     : Hexbus interface
13280
81    Modes:
82         - Compatibility mode (TI-99/4A mode): Memory-mapped devices are
83           placed at the same location as found in the TI-99/4A, thereby
84           providing a good downward compatibility.
85           The console starts up in compatibility mode.
86         - Native mode (Armadillo mode): Devices are located at positions above
87           0xF000 that allow for a contiguous usage of memory.
13388
134Memory map (TMS9901 P5 == 0):
135    When TMS9901 P5 output is cleared, locations >f840->f8ff(?) are ignored by
136    mapper.
137    * >f840: data port for P-code grom library 0 (r?)
138    * >f880: data port for P-code grom library 1 (r?)
139    * >f8c0: data port for P-code grom library 2 (r?)
140    * >f842: address port for P-code grom library 0 (r/w?)
141    * >f882: address port for P-code grom library 1 (r/w?)
142    * >f8c2: address port for P-code grom library 2 (r/w?)
14389
90    ROM contents
91    ------------
92    The ROM0 chip is accessible at addresses 0000-1FFF in the logical address
93    space of the compatibility mode. It contains the GPL interpreter. In
94    native mode the ROM0 chip is invisible.
14495
145Cassette interface:
146    Identical to ti99/4(a), except that the CS2 unit is not implemented.
96      ROM0
97      offset  Logical address     Name
98      -----------------------------------
99      0000    0000-1FFF           ROM0
147100
148101
149Keyboard interface:
150    The keyboard interface uses the console tms9901 PSI, but the pin assignment
151    and key matrix are different from both 99/4 and 99/4a.
152    - P0-P3: column select
153    - INT6*-INT11*: row inputs (int6* is only used for joystick fire)
102    The ROM1 chip contains 32 KiB of various system software. It is located in
103    the physical address space, so it must be mapped into the logical address
104    space by defining an appropriate map.
154105
155ROM file contents:
156  0000-1fff ROM0                0x0000 (logical address)
157  2000-3fff ROM1                0xffa000 - 0xffbfff
158  4000-5fff DSR1                0xff4000 (TTS)
159  6000-7fff ROM1a               0xffc000 - 0xffdfff
160  8000-9fff DSR2                0xff4000 (missing; Hexbus?)
106      ROM1
107      offset  Physical address            Name
108      ----------------------------------------------------------
109      0000    FFA000-FFDFFF               ROM1
110      4000    FF4000-FF5FFF @CRU>2700     Text-to-speech ROM/DSR
111      6000    FF4000-FF5FFF @CRU>1700     Hexbus DSR
161112
113    The DSR portions have to be selected via the CRU bits >1700 or >2700.
114
115
116    Mapper
117    ------
118    The mapper uses 4K pages (unlike the Geneve mapper with 8K pages) which
119    are defined by a 32 bit word. The address bits A0-A3 serve as the page
120    index, whereas bits A4-A15 are the offset in the page.
121    From the 32 bits, 24 bits define the physical address, so this allows for
122    a maximum of 16 MiB of mapped-addressable memory.
123
124    See more about the mapper in the file mapper8.c.
125
126
127    Availability of ROMs and documentation
128    --------------------------------------
129    By written consent, TI granted free use of all software and documentation
130    concerning the TI-99/8, including all specifications, ROMs, and source code
131    of ROMs.
132
133
134    Acknowledgements
135    ----------------
136    Special thanks go to Ciro Barile of the TI99 Italian User Club
137    (www.ti99iuc.it): By his courtesy we have a consistent dump of ROMs for
138    one of the most evolved versions of the TI-99/8 with
139
140    - complete GROM set (with Pascal)
141    - complete ROM set (with Hexbus DSR and TTS)
142    - complete speech ROM set
143
144    Also, by applying test programs on his real console, many unclear
145    specifications were resolved.
146
147
148    References
149    ----------
150    [1] Texas Instruments: Armadillo Product Specifications, July 1983
151    [2] Source code (Assembler and GPL) of the TI-99/8 ROMs and GROMs
152    [3] Schematics of the TI-99/8
153
154
155    Implementation
156    --------------
157    Initial version by Raphael Nabet, 2003.
158
159    February 2012: Rewritten as class [Michael Zapf]
160    November 2013: Included new dumps [Michael Zapf]
161
162162===========================================================================
163163Known Issues (MZ, 2010-11-07)
164164
r26230r26231
172172  emulation for those. Thus you can currently only use cassette to load and
173173  save programs. You MUST not plug in any floppy controller when you intend to
174174  start XB II. Other cartridges (like Editor/Assembler)
175  seem to be not affected by this problem and can make use of the floppy
175  seem to be unaffected by this problem and can make use of the floppy
176176  controllers.
177177    Technical detail: The designers of XB II seem to have decided to put PABs
178178    (Peripheral access block; contains pointers to buffers, the file name, and
r26230r26231
184184    as if XB II does not properly handle this situation and may lock up
185185    (sometimes it starts up, but file access is still not possible).
186186
187    TODO: Emulate a Hexbus floppy.
188
187189- Multiple cartridges are not shown in the startup screen; only one
188190  cartridge is presented. You have to manually select the cartridges with the
189191  dip switch.
r26230r26231
192194  mapper shadows the NVRAM of the cartridge. You will lose the contents when
193195  you turn off the machine.
194196
195    Raphael Nabet, 2003.
196
197    February 2012: Rewritten as class
198    Michael Zapf
199
200197*****************************************************************************/
201198
202199
r26230r26231
217214#include "machine/ti99/gromport.h"
218215#include "machine/ti99/joyport.h"
219216
220#define VERBOSE 1
217// Debugging
218#define TRACE_READY 0
219#define TRACE_INTERRUPTS 0
220#define TRACE_CRU 0
221221#define LOG logerror
222222
223/*
224    READY bits.
225*/
226enum
227{
228   READY_GROM = 1,
229   READY_MAPPER = 2,
230   READY_PBOX = 4,
231   READY_SOUND = 8,
232   READY_CART = 16,
233   READY_SPEECH = 32
234};
235
223236class ti99_8_state : public driver_device
224237{
225238public:
226239   ti99_8_state(const machine_config &mconfig, device_type type, const char *tag)
227240      : driver_device(mconfig, type, tag),
241      m_cpu(*this, "maincpu"),
242      m_tms9901(*this, TMS9901_TAG),
243      m_gromport(*this, GROMPORT_TAG),
244      m_peribox(*this, PERIBOX_TAG),
245      m_mainboard(*this, MAINBOARD8_TAG),
246      m_joyport(*this, JOYPORT_TAG),
247      m_video(*this, VIDEO_SYSTEM_TAG),
228248      m_cassette(*this, "cassette") { }
229249
230   // CRU (Communication Register Unit) handling
231   DECLARE_READ8_MEMBER(cruread);
232   DECLARE_WRITE8_MEMBER(cruwrite);
250   // Machine management
251   DECLARE_MACHINE_START(ti99_8);
252   DECLARE_MACHINE_RESET(ti99_8);
233253
234   DECLARE_WRITE8_MEMBER(external_operation);
254   // Processor connections with the main board
255   DECLARE_READ8_MEMBER( cruread );
256   DECLARE_WRITE8_MEMBER( cruwrite );
257   DECLARE_WRITE8_MEMBER( external_operation );
258   DECLARE_WRITE_LINE_MEMBER( clock_out );
235259
236   // Forwarding interrupts to the CPU or CRU
237   DECLARE_WRITE_LINE_MEMBER( console_ready );
260   // Connections from outside towards the CPU (callbacks)
238261   DECLARE_WRITE_LINE_MEMBER( console_ready_mapper );
262   DECLARE_WRITE_LINE_MEMBER( console_ready_sound );
263   DECLARE_WRITE_LINE_MEMBER( console_ready_pbox );
264   DECLARE_WRITE_LINE_MEMBER( console_ready_cart );
265   DECLARE_WRITE_LINE_MEMBER( console_ready_grom );
266   DECLARE_WRITE_LINE_MEMBER( console_ready_speech );
239267   DECLARE_WRITE_LINE_MEMBER( console_reset );
240
241   DECLARE_WRITE_LINE_MEMBER( set_tms9901_INT2 );
242268   DECLARE_WRITE_LINE_MEMBER( extint );
243269   DECLARE_WRITE_LINE_MEMBER( notconnected );
244270
271   // Connections with the system interface chip 9901
272   DECLARE_WRITE_LINE_MEMBER( set_tms9901_INT2 );
273
274   DECLARE_WRITE_LINE_MEMBER( set_tms9901_INT12 );
275   DECLARE_WRITE_LINE_MEMBER( set_tms9901_INT2_from_v9938);
276
245277   // Connections with the system interface TMS9901
246278   DECLARE_READ8_MEMBER(read_by_9901);
247279   DECLARE_WRITE_LINE_MEMBER(keyC0);
r26230r26231
255287   DECLARE_WRITE_LINE_MEMBER(cassette_motor);
256288   DECLARE_WRITE8_MEMBER(tms9901_interrupt);
257289
258   DECLARE_WRITE_LINE_MEMBER( clock_out );
259   virtual void machine_start();
260   virtual void machine_reset();
261
262   // Some values to keep
263   tms9995_device      *m_cpu;
264   tms9901_device      *m_tms9901;
265   gromport_device     *m_gromport;
266   peribox_device      *m_peribox;
267   ti998_mapper_device *m_mapper;
268   joyport_device*     m_joyport;
269   ti_video_device*    m_video;
270
271   int     m_firstjoy;         // First joystick. 14 for TI-99/8
272
273   int     m_ready_line, m_ready_line1;
274
275290private:
276   /* Keyboard support */
291   // Keyboard support
277292   void    set_keyboard_column(int number, int data);
278293   int     m_keyboard_column;
279   //int     m_alphalock_line;
294
295   // READY handling
296   int     m_nready_combined;
297   int     m_nready_prev;
298   void    console_ready_join(int id, int state);
299
300   // Connected devices
301   required_device<tms9995_device>     m_cpu;
302   required_device<tms9901_device>     m_tms9901;
303   required_device<gromport_device>    m_gromport;
304   required_device<peribox_device>     m_peribox;
305   required_device<mainboard8_device>  m_mainboard;
306   required_device<joyport_device>     m_joyport;
307   required_device<ti_video_device>    m_video;
280308   required_device<cassette_image_device> m_cassette;
281309};
282310
r26230r26231
285313    job to the mapper completely.
286314*/
287315static ADDRESS_MAP_START(memmap, AS_PROGRAM, 8, ti99_8_state)
288   AM_RANGE(0x0000, 0xffff) AM_DEVREADWRITE(MAPPER_TAG, ti998_mapper_device, readm, writem )
316   AM_RANGE(0x0000, 0xffff) AM_DEVREADWRITE(MAINBOARD8_TAG, mainboard8_device, readm, writem )
289317ADDRESS_MAP_END
290318
291319/*
r26230r26231
408436/*****************************************************************************
409437    Components
410438******************************************************************************/
439#define region_sysgrom "sysgrom"
411440
412441static GROM_CONFIG(grom0_config)
413442{
414   false, 0, region_grom, 0x0000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ
443   false, 0, region_sysgrom, 0x0000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ
415444};
416445
417446static GROM_CONFIG(grom1_config)
418447{
419   false, 1, region_grom, 0x2000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ
448   false, 1, region_sysgrom, 0x2000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ
420449};
421450
422451static GROM_CONFIG(grom2_config)
423452{
424   false, 2, region_grom, 0x4000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ
453   false, 2, region_sysgrom, 0x4000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ
425454};
426455
427456/****************************************************
r26230r26231
429458    Do some macro tricks to keep writing effort low
430459*****************************************************/
431460
432#define pascal0_region "pascal0_region"
433#define pascal12_region "pascal12_region"
461#define region_gromlib1 "gromlib1"
462#define region_gromlib2 "gromlib2"
463#define region_gromlib3 "gromlib3"
434464
435#define MCFG_GROM_LIBRARY_ADD(_tag, _config)    \
465#define MCFG_GROM_LIBRARY_ADD8(_tag, _config)    \
436466   MCFG_DEVICE_ADD(#_tag "0", GROM, 0) \
437467   MCFG_DEVICE_CONFIG(_config##0) \
438468   MCFG_DEVICE_ADD(#_tag "1", GROM, 0) \
r26230r26231
450480   MCFG_DEVICE_ADD(#_tag "7", GROM, 0) \
451481   MCFG_DEVICE_CONFIG(_config##7)
452482
483#define MCFG_GROM_LIBRARY_ADD3(_tag, _config)    \
484   MCFG_DEVICE_ADD(#_tag "0", GROM, 0) \
485   MCFG_DEVICE_CONFIG(_config##0) \
486   MCFG_DEVICE_ADD(#_tag "1", GROM, 0) \
487   MCFG_DEVICE_CONFIG(_config##1) \
488   MCFG_DEVICE_ADD(#_tag "2", GROM, 0) \
489   MCFG_DEVICE_CONFIG(_config##2)
490
453491#define GROM_LIBRARY_CONFIG(_conf, _region) \
454492static GROM_CONFIG(_conf##0) \
455{   false, 0, _region, 0x0000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ }; \
493{   false, 0, _region, 0x0000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ }; \
456494static GROM_CONFIG(_conf##1) \
457{   false, 1, _region, 0x2000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ }; \
495{   false, 1, _region, 0x2000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ }; \
458496static GROM_CONFIG(_conf##2) \
459{   false, 2, _region, 0x4000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ }; \
497{   false, 2, _region, 0x4000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ }; \
460498static GROM_CONFIG(_conf##3) \
461{   false, 3, _region, 0x6000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ }; \
499{   false, 3, _region, 0x6000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ }; \
462500static GROM_CONFIG(_conf##4) \
463{   false, 4, _region, 0x8000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ }; \
501{   false, 4, _region, 0x8000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ }; \
464502static GROM_CONFIG(_conf##5) \
465{   false, 5, _region, 0xa000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ }; \
503{   false, 5, _region, 0xa000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ }; \
466504static GROM_CONFIG(_conf##6) \
467{   false, 6, _region, 0xc000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ }; \
505{   false, 6, _region, 0xc000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ }; \
468506static GROM_CONFIG(_conf##7) \
469{   false, 7, _region, 0xe000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready), GROMFREQ };
507{   false, 7, _region, 0xe000, 0x1800, DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_grom), GROMFREQ };
470508
471GROM_LIBRARY_CONFIG(pascal0, pascal0_region)
472GROM_LIBRARY_CONFIG(pascal1, pascal12_region)
473GROM_LIBRARY_CONFIG(pascal2, pascal12_region)
509GROM_LIBRARY_CONFIG(pascal1, region_gromlib1)
510GROM_LIBRARY_CONFIG(pascal2, region_gromlib2)
511GROM_LIBRARY_CONFIG(pascal3, region_gromlib3)
474512
475513static GROMPORT_CONFIG(console_cartslot)
476514{
477   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready),
515   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_cart),
478516   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_reset)
479517};
480518
r26230r26231
482520{
483521   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, extint),         // INTA
484522   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, notconnected),       // INTB
485   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready),  // READY
523   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_pbox),  // READY
486524   0x70000                                             // Address bus prefix (AMA/AMB/AMC)
487525};
488526
r26230r26231
494532   // Similar to the bus8z_devices, just let the mapper, the gromport, and the p-box
495533   // decide whether they want to change the value at the CRU address
496534   // Also, we translate the bit addresses to base addresses
497   m_mapper->crureadz(space, offset<<4, &value);
535   m_mainboard->crureadz(space, offset<<4, &value);
498536   m_gromport->crureadz(space, offset<<4, &value);
499537   m_peribox->crureadz(space, offset<<4, &value);
500538
501   if (VERBOSE>8) LOG("ti99_8: CRU %04x -> %02x\n", offset<<4, value);
539   if (TRACE_CRU) LOG("ti99_8: CRU %04x -> %02x\n", offset<<4, value);
502540   return value;
503541}
504542
505543WRITE8_MEMBER( ti99_8_state::cruwrite )
506544{
507   if (VERBOSE>8) LOG("ti99_8: CRU %04x <- %x\n", offset<<1, data);
508   m_mapper->cruwrite(space, offset<<1, data);
545   if (TRACE_CRU) LOG("ti99_8: CRU %04x <- %x\n", offset<<1, data);
546   m_mainboard->cruwrite(space, offset<<1, data);
509547   m_gromport->cruwrite(space, offset<<1, data);
510548   m_peribox->cruwrite(space, offset<<1, data);
511549}
r26230r26231
539577      // bit 6-7: keyboard status bits 0 through 1
540578
541579      // |K|K|-|-|-|I2|I1|C|
542      if (m_keyboard_column >= m_firstjoy)
580      if (m_keyboard_column >= 14)
543581      {
544582         // TI-99/8's wiring differs from the TI-99/4A
545583         joyst = m_joyport->read_port();
r26230r26231
563601
564602      // |0|0|0|0|0|K|K|K|
565603
566      if (m_keyboard_column >= m_firstjoy)
604      if (m_keyboard_column >= 14)
567605      {
568606         joyst = m_joyport->read_port();
569607         answer = joyst << 1;
r26230r26231
600638   if (data != 0)      m_keyboard_column |= 1 << number;
601639   else                m_keyboard_column &= ~(1 << number);
602640
603   if (m_keyboard_column >= m_firstjoy)
641   if (m_keyboard_column >= 14)
604642   {
605      m_joyport->write_port(m_keyboard_column - m_firstjoy + 1);
643      m_joyport->write_port(m_keyboard_column - 13);
606644   }
607645}
608646
r26230r26231
631669*/
632670WRITE_LINE_MEMBER( ti99_8_state::CRUS )
633671{
634   m_mapper->CRUS_set(state==ASSERT_LINE);
672   m_mainboard->CRUS_set(state==ASSERT_LINE);
635673   if (state==ASSERT_LINE)
636674   {
637675      m_gromport->set_grom_base(0x9800, 0xfbf1);
r26230r26231
647685*/
648686WRITE_LINE_MEMBER( ti99_8_state::PTGEN )
649687{
650   m_mapper->PTGE_set(state==CLEAR_LINE);
688   m_mainboard->PTGE_set(state==CLEAR_LINE);
651689}
652690
653691/*
r26230r26231
720758*/
721759WRITE_LINE_MEMBER( ti99_8_state::set_tms9901_INT2 )
722760{
723   if (VERBOSE>6) LOG("ti99_8: VDP int 2 on tms9901, level=%02x\n", state);
761   if (TRACE_INTERRUPTS) LOG("ti99_8: VDP int 2 on tms9901, level=%02x\n", state);
724762   m_tms9901->set_single_int(2, state);
725763}
726764
r26230r26231
728766    Links to external devices
729767***********************************************************/
730768
769/*
770    We combine the incoming READY signals and propagate them to the CPU.
771    An alternative would be to let the CPU get the READY state, but this would
772    be a much higher overhead, as this happens in each clock tick.
773*/
774void ti99_8_state::console_ready_join(int id, int state)
775{
776   if (state==CLEAR_LINE)
777      m_nready_combined |= id;
778   else
779      m_nready_combined &= ~id;
731780
732WRITE_LINE_MEMBER( ti99_8_state::console_ready )
781   if (TRACE_READY)
782   {
783      if (m_nready_prev != m_nready_combined) LOG("ti99_8: READY bits = %04x\n", ~m_nready_combined);
784   }
785
786   m_nready_prev = m_nready_combined;
787   m_cpu->set_ready(m_nready_combined==0);
788}
789
790/*
791    Connections to the READY line. This might look a bit ugly; we need an
792    implementation of a "Wired AND" device.
793*/
794WRITE_LINE_MEMBER( ti99_8_state::console_ready_grom )
733795{
734   if (VERBOSE>6) LOG("ti99_8: READY level=%02x\n", state);
735   m_ready_line = state;
796   console_ready_join(READY_GROM, state);
797}
736798
737   m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE);
799WRITE_LINE_MEMBER( ti99_8_state::console_ready_mapper )
800{
801   console_ready_join(READY_MAPPER, state);
738802}
739803
804WRITE_LINE_MEMBER( ti99_8_state::console_ready_pbox )
805{
806   console_ready_join(READY_PBOX, state);
807}
808
809WRITE_LINE_MEMBER( ti99_8_state::console_ready_sound )
810{
811   console_ready_join(READY_SOUND, state);
812}
813
814WRITE_LINE_MEMBER( ti99_8_state::console_ready_cart )
815{
816   console_ready_join(READY_CART, state);
817}
818
819WRITE_LINE_MEMBER( ti99_8_state::console_ready_speech )
820{
821   console_ready_join(READY_SPEECH, state);
822}
823
740824/*
741825    The RESET line leading to a reset of the CPU.
742826*/
r26230r26231
749833   }
750834}
751835
752/*
753    Memory access over the mapper also operates
754    the READY line, and the mapper raises READY depending on the clock pulse.
755    So we must make sure this does not interfere.
756*/
757WRITE_LINE_MEMBER( ti99_8_state::console_ready_mapper )
758{
759   if (VERBOSE>6) LOG("ti99_8: READY level (mapper) = %02x\n", state);
760   m_ready_line1 = state;
761   m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE);
762}
763
764836WRITE_LINE_MEMBER( ti99_8_state::extint )
765837{
766   if (VERBOSE>6) LOG("ti99_8: EXTINT level = %02x\n", state);
838   if (TRACE_READY) LOG("ti99_8: EXTINT level = %02x\n", state);
767839   if (m_tms9901 != NULL)
768840      m_tms9901->set_single_int(1, state);
769841}
770842
771843WRITE_LINE_MEMBER( ti99_8_state::notconnected )
772844{
773   if (VERBOSE>6) LOG("ti99_8: Setting a not connected line ... ignored\n");
845   if (TRACE_READY) LOG("ti99_8: Setting a not connected line ... ignored\n");
774846}
775847
776848static TMS9928A_INTERFACE(ti99_8_tms9118a_interface)
r26230r26231
782854WRITE8_MEMBER( ti99_8_state::external_operation )
783855{
784856   static const char* extop[8] = { "inv1", "inv2", "IDLE", "RSET", "inv3", "CKON", "CKOF", "LREX" };
785   if (VERBOSE>1) LOG("External operation %s not implemented on TI-99 board\n", extop[offset]);
857   if (offset == IDLE_OP) return;
858   else
859   {
860      LOG("ti99_4x: External operation %s not implemented on TI-99/8 board\n", extop[offset]);
861   }
786862}
787863
788864/*
r26230r26231
790866*/
791867WRITE_LINE_MEMBER( ti99_8_state::clock_out )
792868{
793   m_mapper->clock_in(state);
869   m_mainboard->clock_in(state);
794870}
795871
796872/*****************************************************************************/
r26230r26231
813889
814890static TI_SOUND_CONFIG( sound_conf )
815891{
816   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready)   // READY
892   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_sound)   // READY
817893};
818894
819895/*
r26230r26231
836912    Access to the mapper registers is done directly in the mapper, not via
837913    this list.
838914
839    NOTE: The available system software contradicts the specification
840    concerning the Pascal ports. While the specs define f840 as "Text-to-speech
841    library" and f850 and f860 as two libraries for Pascal, the operating
842    system defines f840 as Pascal lib 0, f880 as Pascal lib 1, and f8c0 as
843    Pascal lib 2.
844
845915    TODO: This should (must) be improved in terms of performance. Every single
846916    memory access goes through the mapper. Either we use an ordered search list,
847917    or we order the entries according to their frequency.
848918    (I did this right now, putting the Pascal GROMs at the end.)
849919    We should think about a set entry where devices with the same address
850    are collected as one single entry (think about the Pascal lib with 24 GROMs,
851    every eight of them on the same address).
920    are collected as one single entry (think about the Pascal lib with 21 GROMs,
921    twice eight and once three of them on the same address).
852922*/
853923
854#define PASCAL_GROM_LIB(_tag, _addr) \
924#define PASCAL_GROM_LIB8(_tag, _addr) \
855925   { _tag "0",     PATGEN, CONT, _addr, 0xfff1, 0x0000    },   \
856926   { _tag "1",     PATGEN, CONT, _addr, 0xfff1, 0x0000    },   \
857927   { _tag "2",     PATGEN, CONT, _addr, 0xfff1, 0x0000    },   \
r26230r26231
861931   { _tag "6",     PATGEN, CONT, _addr, 0xfff1, 0x0000    },   \
862932   { _tag "7",     PATGEN, CONT, _addr, 0xfff1, 0x0000    }
863933
934#define PASCAL_GROM_LIB3(_tag, _addr) \
935   { _tag "0",     PATGEN, CONT, _addr, 0xfff1, 0x0000    },   \
936   { _tag "1",     PATGEN, CONT, _addr, 0xfff1, 0x0000    },   \
937   { _tag "2",     PATGEN, CONT, _addr, 0xfff1, 0x0000    }
864938
939
865940static const mapper8_list_entry mapper_devices[] =
866941{
867942   // TI-99/4A mode (CRUS=1)
r26230r26231
870945   // (99/4A supports 256 libraries)
871946   // at 9800, 9804, 9808, 980c. Address counter access is at 9802,6,a,e. Write access +0400.
872947   { ROM0NAME,         TI99EM, STOP, 0x0000, 0xe000, 0x0000    },  // 0000-1fff
873
874948   { TISOUND_TAG,      TI99EM, STOP, 0x8400, 0xfff1, 0x0000    },  // 8400-840f
875949   { VIDEO_SYSTEM_TAG, TI99EM, STOP, 0x8800, 0xfff1, 0x0400    },  // 8800,8802 / 8c00,8c02
876950   { SPEECH_TAG,       TI99EM, STOP, 0x9000, 0xfff1, 0x0400    },  // 9000-900f / 9400-940f
877951   { SRAMNAME,         TI99EM, STOP, 0x8000, 0xf800, 0x0000    },  // 8000-87ff; must follow the sound generator
878   { MAPPER_TAG,       TI99EM, STOP, 0x8810, 0xfff0, 0x0000    },
952   { MAINBOARD8_TAG,   TI99EM, STOP, 0x8810, 0xfff0, 0x0000    },
879953
880954   { GROM0_TAG,        TI99EM, CONT, 0x9800, 0xfff1, 0x0400    },  // 9800,2,4,...e/9c00,2,4,...e
881955   { GROM1_TAG,        TI99EM, CONT, 0x9800, 0xfff1, 0x0400    },  // dto.
r26230r26231
893967   { TISOUND_TAG,      NATIVE, STOP, 0xf800, 0xfff1, 0x0000    },  // f800-f80e (even addresses)
894968   { VIDEO_SYSTEM_TAG, NATIVE, STOP, 0xf810, 0xfff1, 0x0000    },  // f810,2 (unlike 99/4A, no different read/write ports)
895969   { SPEECH_TAG,       NATIVE, STOP, 0xf820, 0xfff1, 0x0000    },  // f820-f82f
896   { MAPPER_TAG,       NATIVE, STOP, 0xf870, 0xfff0, 0x0000    },
970   { MAINBOARD8_TAG,   NATIVE, STOP, 0xf870, 0xfff0, 0x0000    },
897971
898972   { GROM0_TAG,        NATIVE, CONT, 0xf830, 0xfff1, 0x0000    },  // f830-f83e (4 banks), no different read/write ports
899973   { GROM1_TAG,        NATIVE, CONT, 0xf830, 0xfff1, 0x0000    },
900974   { GROM2_TAG,        NATIVE, CONT, 0xf830, 0xfff1, 0x0000    },
901975   { GROMPORT_TAG,     NATIVE, CONT, 0xf830, 0xfff1, 0x0000    },
902976
903   PASCAL_GROM_LIB("pascal0_grom", 0xf840),
904   PASCAL_GROM_LIB("pascal1_grom", 0xf880),        // lib1 and 2 are zeroed. We don't have good dumps for them yet.
905   PASCAL_GROM_LIB("pascal2_grom", 0xf8c0),        // Anyway, we keep them in order to check whether/when they are accessed.
977   PASCAL_GROM_LIB8("pascal1_grom", 0xf840),
978   PASCAL_GROM_LIB8("pascal2_grom", 0xf850),
979   PASCAL_GROM_LIB3("pascal3_grom", 0xf860),
906980
907981   // Physical (need to pack this in here as well to keep config simple)
908982   // but these lines will be put into a separate list
909983   { DRAMNAME,         PHYSIC, STOP, 0x000000, 0xff0000, 0x000000  },  // 000000-00ffff 64 KiB DRAM
910   { MAPPER_TAG,       PHYSIC, CONT, 0xff4000, 0xffe000, 0x000000  },  // ff4000-ff5fff Internal DSR
984   { MAINBOARD8_TAG,   PHYSIC, CONT, 0xff4000, 0xffe000, 0x000000  },  // ff4000-ff5fff Internal DSR
911985   { GROMPORT_TAG,     PHYSIC, STOP, 0xff6000, 0xffe000, 0x000000  },  // ff6000-ff7fff Cartridge ROM space
912986   { GROMPORT_TAG,     PHYSIC, STOP, 0xff8000, 0xffe000, 0x000000  },  // ff8000-ff9fff Cartridge ROM space
913   { ROM1NAME,         PHYSIC, STOP, 0xffa000, 0xffe000, 0x000000  },  // ffa000-ffbfff ROM1
914   { ROM1ANAME,        PHYSIC, STOP, 0xffc000, 0xffe000, 0x000000  },  // ffc000-ffdfff ROM1
987   { ROM1A0NAME,       PHYSIC, STOP, 0xffa000, 0xffe000, 0x000000  },  // ffa000-ffbfff ROM1
988   { ROM1C0NAME,       PHYSIC, STOP, 0xffc000, 0xffe000, 0x000000  },  // ffc000-ffdfff ROM1
915989   { INTSNAME,         PHYSIC, STOP, 0xffe000, 0xfffff0, 0x000000  },  // ffe000-ffe00f Interrupt level sense
916990   { PERIBOX_TAG,      PHYSIC, STOP, 0x000000, 0x000000, 0x000000  },  // Peripheral Expansion Box
917991
r26230r26231
9261000
9271001static SPEECH8_CONFIG( speech_config )
9281002{
929   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready),  // READY
1003   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, console_ready_speech),  // READY
9301004};
9311005
9321006static JOYPORT_CONFIG( joyport8_60 )
r26230r26231
9411015   50
9421016};
9431017
944void ti99_8_state::machine_start()
1018MACHINE_START_MEMBER(ti99_8_state,ti99_8)
9451019{
946   m_cpu = static_cast<tms9995_device*>(machine().device("maincpu"));
947   m_tms9901 = static_cast<tms9901_device*>(machine().device(TMS9901_TAG));
948   m_gromport = static_cast<gromport_device*>(machine().device(GROMPORT_TAG));
949   m_peribox = static_cast<peribox_device*>(machine().device(PERIBOX_TAG));
950   m_mapper = static_cast<ti998_mapper_device*>(machine().device(MAPPER_TAG));
951   m_joyport = static_cast<joyport_device*>(machine().device(JOYPORT_TAG));
952   m_video = static_cast<ti_video_device*>(machine().device(VIDEO_SYSTEM_TAG));
953
1020   m_nready_combined = 0;
9541021   m_peribox->senila(CLEAR_LINE);
9551022   m_peribox->senilb(CLEAR_LINE);
956   m_firstjoy = 14;
9571023}
9581024
959void ti99_8_state::machine_reset()
1025MACHINE_RESET_MEMBER(ti99_8_state, ti99_8)
9601026{
9611027   m_cpu->set_hold(CLEAR_LINE);
9621028
9631029   // Pulling down the line on RESET configures the CPU to insert one wait
9641030   // state on external memory accesses
965
966   // RN: enable automatic wait state generation
967   // in January 83 99/8 schematics sheet 9: the delay logic
968   // seems to keep READY low for one cycle when RESET* is
969   // asserted, but the timings are completely wrong this way
970
9711031   m_cpu->set_ready(CLEAR_LINE);
9721032
9731033   // But we assert the line here so that the system starts running
974   m_ready_line = m_ready_line1 = ASSERT_LINE;
1034   m_nready_combined = 0;
9751035   m_gromport->set_grom_base(0x9800, 0xfff1);
9761036}
9771037
r26230r26231
9791039   /* basic machine hardware */
9801040   /* TMS9995-MP9537 CPU @ 10.7 MHz */
9811041   MCFG_TMS99xx_ADD("maincpu", TMS9995, 10738635, memmap, crumap, ti99_8_processor_config)
1042   MCFG_MACHINE_START_OVERRIDE(ti99_8_state, ti99_8 )
1043   MCFG_MACHINE_RESET_OVERRIDE(ti99_8_state, ti99_8 )
9821044
9831045   /* Video hardware */
9841046   MCFG_TI998_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9118, ti99_8_tms9118a_interface)
9851047
9861048   /* Main board */
9871049   MCFG_TMS9901_ADD( TMS9901_TAG, tms9901_wiring_ti99_8, 2684658.75 )
988   MCFG_MAPPER8_ADD( MAPPER_TAG, mapper_conf )
1050   MCFG_MAINBOARD8_ADD( MAINBOARD8_TAG, mapper_conf )
9891051   MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG, console_cartslot )
9901052
9911053   /* Peripheral expansion box */
r26230r26231
10061068   MCFG_GROM_ADD( GROM2_TAG, grom2_config )
10071069
10081070   /* Pascal GROM libraries. */
1009   MCFG_GROM_LIBRARY_ADD(pascal0_grom, pascal0)
1010   MCFG_GROM_LIBRARY_ADD(pascal1_grom, pascal1)
1011   MCFG_GROM_LIBRARY_ADD(pascal2_grom, pascal2)
1071   MCFG_GROM_LIBRARY_ADD8(pascal1_grom, pascal1)
1072   MCFG_GROM_LIBRARY_ADD8(pascal2_grom, pascal2)
1073   MCFG_GROM_LIBRARY_ADD3(pascal3_grom, pascal3)
10121074
10131075   /* Devices */
10141076   MCFG_TISPEECH8_ADD(SPEECH_TAG, speech_config)
r26230r26231
10221084   /* basic machine hardware */
10231085   /* TMS9995-MP9537 CPU @ 10.7 MHz */
10241086   MCFG_TMS99xx_ADD("maincpu", TMS9995, 10738635, memmap, crumap, ti99_8_processor_config)
1087   MCFG_MACHINE_START_OVERRIDE(ti99_8_state, ti99_8 )
1088   MCFG_MACHINE_RESET_OVERRIDE(ti99_8_state, ti99_8 )
10251089
10261090   /* Video hardware */
10271091   MCFG_TI998_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9129, ti99_8_tms9118a_interface)
10281092
10291093   /* Main board */
10301094   MCFG_TMS9901_ADD( TMS9901_TAG, tms9901_wiring_ti99_8, 2684658.75 )
1031   MCFG_MAPPER8_ADD( MAPPER_TAG, mapper_conf )
1095   MCFG_MAINBOARD8_ADD( MAINBOARD8_TAG, mapper_conf )
10321096   MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG, console_cartslot )
10331097
10341098   /* Peripheral expansion box */
r26230r26231
10481112   MCFG_GROM_ADD( GROM1_TAG, grom1_config )
10491113   MCFG_GROM_ADD( GROM2_TAG, grom2_config )
10501114
1051   /* Pascal GROMs libraries. */
1052   MCFG_GROM_LIBRARY_ADD(pascal0_grom, pascal0)
1053   MCFG_GROM_LIBRARY_ADD(pascal1_grom, pascal1)
1054   MCFG_GROM_LIBRARY_ADD(pascal2_grom, pascal2)
1115   /* Pascal GROM libraries. */
1116   MCFG_GROM_LIBRARY_ADD8(pascal1_grom, pascal1)
1117   MCFG_GROM_LIBRARY_ADD8(pascal2_grom, pascal2)
1118   MCFG_GROM_LIBRARY_ADD3(pascal3_grom, pascal3)
10551119
10561120   /* Devices */
10571121   MCFG_TISPEECH8_ADD(SPEECH_TAG, speech_config)
r26230r26231
10641128    ROM loading
10651129*/
10661130ROM_START(ti99_8)
1067   /*CPU memory space*/
1068   ROM_REGION(0x8000,"maincpu",0)
1069   ROM_LOAD("998rom.bin", 0x0000, 0x8000, CRC(b7a06ffd) SHA1(17dc8529fa808172fc47089982efb0bf0548c80c))        /* system ROMs */
1131   // Logical (CPU) memory space: ROM0
1132   ROM_REGION(0x2000, ROM0_TAG, 0)
1133   ROM_LOAD("u4_rom0.bin", 0x0000, 0x2000, CRC(901eb8d6) SHA1(13190c5e834baa9c0a70066b566cfcef438ed88a))
10701134
1071   /*GROM memory space*/
1072   ROM_REGION(0x10000, region_grom, 0)
1073   ROM_LOAD("998grom.bin", 0x0000, 0x6000, CRC(c63806bc) SHA1(cbfa8b04b4aefbbd9a713c54267ad4dd179c13a3))   /* system GROMs */
1135   // Physical memory space: ROM1
1136   ROM_REGION(0x8000, ROM1_TAG, 0)
1137   ROM_LOAD("u25_rom1.bin", 0x0000, 0x8000, CRC(5df17dfa) SHA1(134ae025f1b43f8e0e2aef4278f9d0c9fcffd68e))
10741138
1075   /* Pascal GROMs. Sadly, P-System fails to start. */
1076   ROM_REGION(0x10000, pascal0_region, 0)
1077   ROM_LOAD_OPTIONAL("998pascal.bin", 0x0000, 0x10000, CRC(1389589e) SHA1(42942b99ed355a2c091cc480b15f5329156e6b03))
1139   // Speech ROMs
1140   ROM_REGION(0x8000, SPEECH_TAG, 0)
1141   ROM_LOAD("cd2325a.vsm", 0x0000, 0x4000, CRC(1f58b571) SHA1(0ef4f178716b575a1c0c970c56af8a8d97561ffe))
1142   ROM_LOAD("cd2326a.vsm", 0x4000, 0x4000, CRC(65d00401) SHA1(a367242c2c96cebf0e2bf21862f3f6734b2b3020))
10781143
1079   // Still need good dumps; so far, stay with 0
1080   ROM_REGION(0x10000, pascal12_region, 0)
1081   ROM_FILL(0x0000, 0x10000, 0x00)
1144   // System GROMs. 3 chips @ f830
1145   // The schematics do not enumerate the circuits but only show "circuits on board" (COB)
1146   // so we name the roms as gID_port.bin
1147   ROM_REGION(0x6000, region_sysgrom, 0)
1148   ROM_LOAD("g0_f830.bin", 0x0000, 0x1800, CRC(1026db60) SHA1(7327095bf4f390476e69d9fd8424e98ea1f2325a))
1149   ROM_LOAD("g1_f830.bin", 0x2000, 0x1800, CRC(93a43d65) SHA1(19be8a07d674bc7554c2bc9c7a5725d81e888e6e))
1150   ROM_LOAD("g2_f830.bin", 0x4000, 0x1800, CRC(06f2b901) SHA1(f65e0fcb2c63e230b4a9563c72f91259b94ce955))
10821151
1083   /* Built-in RAM */
1152   // TTS & Pascal library. 8 chips @ f840
1153   ROM_REGION(0x10000, region_gromlib1, 0)
1154   ROM_LOAD("g0_f840.bin", 0x0000, 0x1800, CRC(44501071) SHA1(4b5ef7f1aa43a87e7ae4f02090944be5c39b1f26))
1155   ROM_LOAD("g1_f840.bin", 0x2000, 0x1800, CRC(5a271d9e) SHA1(bb95befa2ffba2cc17ac437386e069e8ff621248))
1156   ROM_LOAD("g2_f840.bin", 0x4000, 0x1800, CRC(d52502df) SHA1(17063e33ee8709d0df8030f38bb92c4322d55e1e))
1157   ROM_LOAD("g3_f840.bin", 0x6000, 0x1800, CRC(86c12396) SHA1(119b6df9211b5399245e017721fc51b88b60879f))
1158   ROM_LOAD("g4_f840.bin", 0x8000, 0x1800, CRC(f17a2ef8) SHA1(dcb044f71d7f8a165b41f39e35a368d8f2d63b67))
1159   ROM_LOAD("g5_f840.bin", 0xA000, 0x1800, CRC(7dc41301) SHA1(dff714da68de352db93fba309db8e5a8ae7cab1a))
1160   ROM_LOAD("g6_f840.bin", 0xC000, 0x1800, CRC(7e310a90) SHA1(e927d8b3f8b32aa4fb9f7d080d5262c566a77fc7))
1161   ROM_LOAD("g7_f840.bin", 0xE000, 0x1800, CRC(3a9d20df) SHA1(1e6f9f8ec7df4b997a7579be742d0a7d54bc8763))
1162
1163   // Pascal library. 8 chips @ f850
1164   ROM_REGION(0x10000, region_gromlib2, 0)
1165   ROM_LOAD("g0_f850.bin", 0x0000, 0x1800, CRC(ec59a428) SHA1(be6d47a3497130f22b771c28af50abe632744d70))
1166   ROM_LOAD("g1_f850.bin", 0x2000, 0x1800, CRC(7d64a842) SHA1(d5884bb2af21c8027311478ee506beac6f46203d))
1167   ROM_LOAD("g2_f850.bin", 0x4000, 0x1800, CRC(e5ed8900) SHA1(03826882ce10fb5a6b3a9ccc85d3d1fe51979d0b))
1168   ROM_LOAD("g3_f850.bin", 0x6000, 0x1800, CRC(87aaf19e) SHA1(fdbe163773b8a30fa6b9508e679be6fa4f99bf7a))
1169   ROM_LOAD("g4_f850.bin", 0x8000, 0x1800, CRC(d3e789a5) SHA1(5ab06aa75ca694b1035ce5ac0bebacc928721388))
1170   ROM_LOAD("g5_f850.bin", 0xA000, 0x1800, CRC(49fd90bd) SHA1(44b2cef29c2d5304a0dcfedbdcdf9f21f2201bf9))
1171   ROM_LOAD("g6_f850.bin", 0xC000, 0x1800, CRC(31bac4ab) SHA1(e29049f0597d5de0bfd5c9c7bfea902abe858010))
1172   ROM_LOAD("g7_f850.bin", 0xE000, 0x1800, CRC(71534098) SHA1(75e87123efde885e27dd749e07cb189eb2cc45a8))
1173
1174   // Pascal library. 3 chips @ f860
1175   ROM_REGION(0x6000, region_gromlib3, 0)
1176   ROM_LOAD("g0_f860.bin", 0x0000, 0x1800, CRC(9b7ec501) SHA1(223cc0070429e4a8e3d9fe10f5f660f011fe8fa9))
1177   ROM_LOAD("g1_f860.bin", 0x2000, 0x1800, CRC(fc87de25) SHA1(4695b7f979f59a01ec16c55e4587c3379482b658))
1178   ROM_LOAD("g2_f860.bin", 0x4000, 0x1800, CRC(e833e350) SHA1(6ffe501981a1112be1af596a489d96e287fc6be5))
1179
1180   // Built-in RAM
10841181   ROM_REGION(SRAM_SIZE, SRAM_TAG, 0)
10851182   ROM_FILL(0x0000, SRAM_SIZE, 0x00)
10861183

Previous 199869 Revisions Next


© 1997-2024 The MAME Team