Previous 15994 Revisions Next

r9489 Sunday 31st October, 2010 at 20:27:37 UTC by Robbbert
[TI99] Fixed 2 compilation errors, and commented out the unused variable.
[src/mess/machine/ti99]grom.c gromport.c tn_ide.c

src/mess/machine/ti99/grom.c
r9488r9489
1/***************************************************************************
2
3    GROM emulation (aka TMC0430)
4
5    This is a preliminary implementation since it does not yet contain
6    internal timing; instead, it directly accesses the processor to
7    simulate wait states
8    When this will have become available, the file will be moved to the
9    general circuit collection (emu/machine)
10   
11          +----+--+----+
12      AD7 |1    G    16| Vss             
13      AD6 |2    R    15| GR
14      AD5 |3    O    14| Vdd
15      AD4 |4    M    13| GRC
16      AD3 |5         12| M
17      AD2 |6         11| MO
18      AD1 |7         10| GS*
19      AD0 |8          9| Vcc
20          +------------+
21
22    GR  = GROM Ready. Should be connected to processor's READY/HOLD*.
23    GRC = GROM clock. Typically in the range of 400-500 kHz.
24    M   = Direction. 1=read, 0=write
25    MO  = Mode. 1=address counter access, 0=data access
26    GS* = GROM select. 0=select, 1=deselect
27   
28    Every GROM has an internal ID which represents the high-order three
29    address bits. The address counter can be set to any value from 0
30    to 0xffff; the GROM will only react if selected and if the current
31    address counter's high-order bits match the ID of the chip.
32    Example: When the ID is 6, the GROM will react when the address
33    counter contains a value from 0xc000 to 0xdfff.
34   
35    Writable GROMs are called GRAMs. Although the TI-99 systems reserve a
36    port in the memory space, no one has ever seen a GRAM circuit in the wild.
37    However, third-party products like HSGPL or GRAM Kracker simulate GRAMs
38    using conventional RAM with some addressing circuitry, usually in a custom
39    chip.
40   
41    CHECK: Reading the address increases the counter only once. The first access
42    returns the MSB, the second (and all following accesses) return the LSB.
43   
44    Michael Zapf, August 2010
45   
46***************************************************************************/
47
48#include "emu.h"
49#include "grom.h"
50#include "datamux.h"
51
52/* ti99_grom_state: GROM state */
53struct _ti99grom_state
54{
55   /* Address pointer. */
56   // This value is always expected to be in the range 0x0000 - 0xffff, even
57   // when this GROM is not addressed.
58   UINT16 address;
59
60   /* GROM data buffer. */
61   UINT8 buffer;
62   
63   /* Internal flip-flop. Used when retrieving the address counter. */
64   UINT8 raddr_LSB;
65
66   /* Internal flip-flops. Used when writing the address counter.*/
67   UINT8 waddr_LSB;
68   
69   /* ID of this GROM. */
70   UINT8 ident;
71   
72   /* Pointer to the memory region contained in this GROM. */
73   UINT8 *memptr;
74   
75   /* GROM size. May be 0x1800 or 0x2000. */
76   // If the GROM has only 6 KiB, the remaining 2 KiB are filled with a
77   // specific byte pattern which is created by a logical OR of lower
78   // regions
79   int extended;
80
81   /* Determines whether this is a GRAM. */   
82   int writable;
83
84   /* Determines whether there is a rollover at the end of the address space. */   
85   int rollover;
86   
87   /* Ready callback. This line is usually connected to the READY pin of the CPU. */
88   devcb_resolved_write_line gromready;
89};
90typedef struct _ti99grom_state ti99grom_state;
91
92INLINE ti99grom_state *get_safe_token(running_device *device)
93{
94   assert(device != NULL);
95   assert(downcast<legacy_device_base *>(device)->token() != NULL);
96   return (ti99grom_state *)downcast<legacy_device_base *>(device)->token();
97}
98
99INLINE const ti99grom_config *get_config(running_device *device)
100{
101   assert(device != NULL);
102   assert(device->type() == GROM);
103   return (const ti99grom_config *) downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
104}
105
106/*
107   Indicates whether this chip will react on the next read/write data
108   access. We do not have a tri-state handling on the read handlers, so this
109   serves to avoid the read access.
110*/
111int is_selected(running_device *chip)
112{
113   ti99grom_state *grom = get_safe_token(chip);
114   return (((grom->address >> 13)&0x07)==grom->ident);
115}
116
117/*
118   Reading from the chip. Represents an access with M=1, GS*=0. The MO bit is
119   defined by the offset (0 or 1). This is the enhanced read function with
120   Z state.
121*/
122READ8Z_DEVICE_HANDLER( ti99grom_rz )
123{
124   ti99grom_state *grom = get_safe_token(device);
125     
126   if (offset & 2)
127   {
128      if (((grom->address >> 13)&0x07)!=grom->ident)
129         return;
130
131      /* When reading, reset the hi/lo flag byte for writing. */
132      /* TODO: Verify this with a real machine. */
133      grom->waddr_LSB = FALSE;
134
135      /* Address reading is done in two steps; first, the high byte */
136      /* is transferred, then the low byte. */
137      if (grom->raddr_LSB)
138      {
139         /* second pass */
140         *value = grom->address & 0x00ff;
141         grom->raddr_LSB = FALSE;
142      }
143      else
144      {
145         /* first pass */
146         *value = (grom->address & 0xff00)>>8;
147         grom->raddr_LSB = TRUE;
148      }
149   }
150   else
151   {
152      if (((grom->address >> 13)&0x07)==grom->ident)
153      {
154         /* GROMs are buffered. Data is retrieved from a buffer, */
155         /* while the buffer is replaced with the next cell content. */
156         *value = grom->buffer;
157         
158         /* Get next value, put it in buffer. Note that the GROM */
159         /* wraps at 8K boundaries. */
160         UINT16 addr = grom->address-(grom->ident<<13);
161         
162         if (!grom->extended && ((grom->address&0x1fff)>=0x1800))
163            grom->buffer = grom->memptr[addr-0x1000] | grom->memptr[addr-0x0800];
164         else
165            grom->buffer = grom->memptr[addr];
166      }
167      /* Note that all GROMs update their address counter. */
168      if (grom->rollover)
169         grom->address = ((grom->address + 1) & 0x1FFF) | (grom->address & 0xE000);
170      else
171         grom->address = (grom->address + 1)&0xFFFF;
172
173      /* Reset the read and write address flipflops. */
174      grom->raddr_LSB = grom->waddr_LSB = FALSE;
175   }
176}
177
178/*
179   Reading from the chip. Represents an access with M=1, GS*=0. The MO bit is
180   defined by the offset (0 or 1).
181*/
182READ8_DEVICE_HANDLER( ti99grom_r )
183{
184   UINT8 reply;
185   ti99grom_rz(device, offset, &reply);
186   return reply;
187}
188
189
190/*
191   Writing to the chip. Represents an access with M=0, GS*=0. The MO bit is
192   defined by the offset (0 or 1).
193*/
194WRITE8_DEVICE_HANDLER( ti99grom_w )
195{
196   ti99grom_state *grom = get_safe_token(device);
197   if (offset & 2)
198   {
199      /* write GROM address */
200      /* see comments above */
201      grom->raddr_LSB = FALSE;
202
203      /* Implements the internal flipflop. */
204      /* The Editor/Assembler manuals says that the current address */
205      /* plus one is returned. This effect is properly emulated */
206      /* by using a read-ahead buffer. */
207      if (grom->waddr_LSB)
208      {
209         /* Accept low byte (2nd write) */
210         grom->address = (grom->address & 0xFF00) | data;
211         /* Setting the address causes a new prefetch */
212         if (is_selected(device))
213         {
214            grom->buffer = grom->memptr[grom->address-(grom->ident<<13)];
215         }     
216         grom->waddr_LSB = FALSE;
217      }
218      else
219      {
220         /* Accept high byte (1st write). Do not advance the address conter. */
221         grom->address = (data << 8) | (grom->address & 0xFF);
222         grom->waddr_LSB = TRUE;
223         return;
224      }
225   }
226   else
227   {
228      /* write GRAM data */
229      if ((((grom->address >> 13)&0x07)==grom->ident) && grom->writable)
230      {
231         UINT16 write_addr;
232         // We need to rewind by 1 because the read address has already advanced.
233         // However, do not change the address counter!
234         if (grom->rollover)
235            write_addr = ((grom->address + 0x1fff) & 0x1FFF) | (grom->address & 0xE000);
236         else
237            write_addr = (grom->address - 1) & 0xFFFF;
238         
239         // UINT16 addr = grom->address-(grom->ident<<13);
240         if (grom->extended || ((grom->address&0x1fff)<0x1800))
241            grom->memptr[write_addr-(grom->ident<<13)] = data;
242      }     
243      grom->raddr_LSB = grom->waddr_LSB = FALSE;
244   }
245
246   if (grom->rollover)
247      grom->address = ((grom->address + 1) & 0x1FFF) | (grom->address & 0xE000);
248   else
249      grom->address = (grom->address + 1) & 0xFFFF;
250}
251
252/***************************************************************************
253    DEVICE FUNCTIONS
254***************************************************************************/
255
256static DEVICE_START( ti99grom )
257{
258   ti99grom_state *grom = get_safe_token(device);
259   const ti99grom_config* gromconf = (const ti99grom_config*)get_config(device);
260
261   grom->writable = gromconf->writeable;
262   grom->ident = gromconf->ident;
263   
264   grom->extended = (gromconf->size==0x1800)? TRUE : FALSE;
265
266   grom->rollover = gromconf->rollover;
267
268   devcb_write_line ready = DEVCB_LINE(gromconf->ready);
269   devcb_resolve_write_line(&grom->gromready, &ready, device);
270   // Test
271   // devcb_call_write_line(&grom->gromready, ASSERT_LINE);
272}
273
274static DEVICE_STOP( ti99grom )
275{
276}
277
278static DEVICE_RESET( ti99grom )
279{
280   const ti99grom_config* gromconf = (const ti99grom_config*)get_config(device);
281   ti99grom_state *grom = get_safe_token(device);
282   grom->address = 0;
283   grom->raddr_LSB = FALSE;
284   grom->waddr_LSB = FALSE;
285   grom->buffer = 0;
286
287   /* Try to get the pointer to the memory contents from the parent */
288   if (gromconf->region==NULL)
289      grom->memptr = (*gromconf->get_memory)(device->owner());
290   else
291      grom->memptr = memory_region(device->machine, gromconf->region);
292
293   //  TODO: Check whether this may be 0 for console GROMs.
294   //   assert (grom->memptr!=NULL);
295
296   grom->memptr += gromconf->offset;
297
298   // TODO: If the GROM is a subdevice of another device, and a region
299   // is specified, we need to first determine the device tag and concatenate
300   // the GROM region behind this device tag; otherwise the region will not be
301   // found. May be done with an astring.
302}
303
304static const char DEVTEMPLATE_SOURCE[] = __FILE__;
305
306#define DEVTEMPLATE_ID(p,s)             p##ti99grom##s
307#define DEVTEMPLATE_FEATURES            DT_HAS_START | DT_HAS_STOP | DT_HAS_RESET | DT_HAS_INLINE_CONFIG
308#define DEVTEMPLATE_NAME                "tmc0430"
309#define DEVTEMPLATE_FAMILY              "TTL"
310#include "devtempl.h"
311
312DEFINE_LEGACY_DEVICE( GROM, ti99grom );
1/***************************************************************************
2 
3    GROM emulation (aka TMC0430)
4 
5    This is a preliminary implementation since it does not yet contain 
6    internal timing; instead, it directly accesses the processor to 
7    simulate wait states
8    When this will have become available, the file will be moved to the
9    general circuit collection (emu/machine)
10     
11          +----+--+----+ 
12      AD7 |1    G    16| Vss               
13      AD6 |2    R    15| GR
14      AD5 |3    O    14| Vdd
15      AD4 |4    M    13| GRC 
16      AD3 |5         12| M
17      AD2 |6         11| MO
18      AD1 |7         10| GS*
19      AD0 |8          9| Vcc 
20          +------------+
21 
22    GR  = GROM Ready. Should be connected to processor's READY/HOLD*.
23    GRC = GROM clock. Typically in the range of 400-500 kHz.
24    M   = Direction. 1=read, 0=write
25    MO  = Mode. 1=address counter access, 0=data access
26    GS* = GROM select. 0=select, 1=deselect
27     
28    Every GROM has an internal ID which represents the high-order three 
29    address bits. The address counter can be set to any value from 0
30    to 0xffff; the GROM will only react if selected and if the current
31    address counter's high-order bits match the ID of the chip.
32    Example: When the ID is 6, the GROM will react when the address 
33    counter contains a value from 0xc000 to 0xdfff.
34     
35    Writable GROMs are called GRAMs. Although the TI-99 systems reserve a
36    port in the memory space, no one has ever seen a GRAM circuit in the wild. 
37    However, third-party products like HSGPL or GRAM Kracker simulate GRAMs 
38    using conventional RAM with some addressing circuitry, usually in a custom 
39    chip.
40     
41    CHECK: Reading the address increases the counter only once. The first access
42    returns the MSB, the second (and all following accesses) return the LSB.
43     
44    Michael Zapf, August 2010
45     
46***************************************************************************/
47 
48#include "emu.h"
49#include "grom.h"
50#include "datamux.h"
51 
52/* ti99_grom_state: GROM state */
53struct _ti99grom_state
54{
55   /* Address pointer. */
56   // This value is always expected to be in the range 0x0000 - 0xffff, even
57   // when this GROM is not addressed.
58   UINT16 address;
59 
60   /* GROM data buffer. */
61   UINT8 buffer;
62   
63   /* Internal flip-flop. Used when retrieving the address counter. */
64   UINT8 raddr_LSB;
65 
66   /* Internal flip-flops. Used when writing the address counter.*/
67   UINT8 waddr_LSB;
68   
69   /* ID of this GROM. */
70   UINT8 ident;
71   
72   /* Pointer to the memory region contained in this GROM. */
73   UINT8 *memptr;
74   
75   /* GROM size. May be 0x1800 or 0x2000. */
76   // If the GROM has only 6 KiB, the remaining 2 KiB are filled with a 
77   // specific byte pattern which is created by a logical OR of lower
78   // regions
79   int extended;
80 
81   /* Determines whether this is a GRAM. */   
82   int writable;
83 
84   /* Determines whether there is a rollover at the end of the address space. */   
85   int rollover;
86   
87   /* Ready callback. This line is usually connected to the READY pin of the CPU. */
88   devcb_resolved_write_line gromready;
89};
90typedef struct _ti99grom_state ti99grom_state;
91 
92INLINE ti99grom_state *get_safe_token(running_device *device)
93{
94   assert(device != NULL);
95   assert(downcast<legacy_device_base *>(device)->token() != NULL);
96   return (ti99grom_state *)downcast<legacy_device_base *>(device)->token();
97}
98 
99INLINE const ti99grom_config *get_config(running_device *device)
100{
101   assert(device != NULL);
102   assert(device->type() == GROM);
103   return (const ti99grom_config *) downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
104}
105 
106/*
107   Indicates whether this chip will react on the next read/write data 
108   access. We do not have a tri-state handling on the read handlers, so this
109   serves to avoid the read access.
110*/
111int is_selected(running_device *chip) 
112{
113   ti99grom_state *grom = get_safe_token(chip);
114   return (((grom->address >> 13)&0x07)==grom->ident);
115}
116 
117/*
118   Reading from the chip. Represents an access with M=1, GS*=0. The MO bit is
119   defined by the offset (0 or 1). This is the enhanced read function with 
120   Z state.
121*/
122READ8Z_DEVICE_HANDLER( ti99grom_rz )
123{
124   ti99grom_state *grom = get_safe_token(device);
125       
126   if (offset & 2)
127   {
128      if (((grom->address >> 13)&0x07)!=grom->ident) 
129         return;
130 
131      /* When reading, reset the hi/lo flag byte for writing. */
132      /* TODO: Verify this with a real machine. */
133      grom->waddr_LSB = FALSE;
134 
135      /* Address reading is done in two steps; first, the high byte */
136      /* is transferred, then the low byte. */
137      if (grom->raddr_LSB)
138      {
139         /* second pass */
140         *value = grom->address & 0x00ff;
141         grom->raddr_LSB = FALSE;
142      }
143      else
144      {
145         /* first pass */
146         *value = (grom->address & 0xff00)>>8;
147         grom->raddr_LSB = TRUE;
148      }
149   }
150   else
151   {
152      if (((grom->address >> 13)&0x07)==grom->ident) 
153      {
154         /* GROMs are buffered. Data is retrieved from a buffer, */
155         /* while the buffer is replaced with the next cell content. */
156         *value = grom->buffer;
157         
158         /* Get next value, put it in buffer. Note that the GROM */
159         /* wraps at 8K boundaries. */
160         UINT16 addr = grom->address-(grom->ident<<13);
161         
162         if (!grom->extended && ((grom->address&0x1fff)>=0x1800))
163            grom->buffer = grom->memptr[addr-0x1000] | grom->memptr[addr-0x0800];
164         else
165            grom->buffer = grom->memptr[addr];
166      }
167      /* Note that all GROMs update their address counter. */
168      if (grom->rollover)
169         grom->address = ((grom->address + 1) & 0x1FFF) | (grom->address & 0xE000);
170      else
171         grom->address = (grom->address + 1)&0xFFFF;
172 
173      /* Reset the read and write address flipflops. */
174      grom->raddr_LSB = grom->waddr_LSB = FALSE;
175   }
176}
177 
178/*
179   Reading from the chip. Represents an access with M=1, GS*=0. The MO bit is
180   defined by the offset (0 or 1).
181*/
182READ8_DEVICE_HANDLER( ti99grom_r )
183{
184   UINT8 reply = 0;
185   ti99grom_rz(device, offset, &reply); 
186   return reply;
187}
188 
189 
190/*
191   Writing to the chip. Represents an access with M=0, GS*=0. The MO bit is
192   defined by the offset (0 or 1).
193*/
194WRITE8_DEVICE_HANDLER( ti99grom_w )
195{
196   ti99grom_state *grom = get_safe_token(device);
197   if (offset & 2)
198   {
199      /* write GROM address */
200      /* see comments above */
201      grom->raddr_LSB = FALSE;
202 
203      /* Implements the internal flipflop. */
204      /* The Editor/Assembler manuals says that the current address */
205      /* plus one is returned. This effect is properly emulated */
206      /* by using a read-ahead buffer. */
207      if (grom->waddr_LSB)
208      {
209         /* Accept low byte (2nd write) */
210         grom->address = (grom->address & 0xFF00) | data;
211         /* Setting the address causes a new prefetch */
212         if (is_selected(device)) 
213         {
214            grom->buffer = grom->memptr[grom->address-(grom->ident<<13)];
215         }       
216         grom->waddr_LSB = FALSE;
217      }
218      else
219      {
220         /* Accept high byte (1st write). Do not advance the address conter. */
221         grom->address = (data << 8) | (grom->address & 0xFF);
222         grom->waddr_LSB = TRUE;
223         return;
224      }
225   }
226   else
227   {
228      /* write GRAM data */
229      if ((((grom->address >> 13)&0x07)==grom->ident) && grom->writable)
230      {
231         UINT16 write_addr;
232         // We need to rewind by 1 because the read address has already advanced.
233         // However, do not change the address counter!
234         if (grom->rollover)
235            write_addr = ((grom->address + 0x1fff) & 0x1FFF) | (grom->address & 0xE000);
236         else
237            write_addr = (grom->address - 1) & 0xFFFF;
238         
239         // UINT16 addr = grom->address-(grom->ident<<13);
240         if (grom->extended || ((grom->address&0x1fff)<0x1800))
241            grom->memptr[write_addr-(grom->ident<<13)] = data;
242      }       
243      grom->raddr_LSB = grom->waddr_LSB = FALSE;
244   }
245 
246   if (grom->rollover)
247      grom->address = ((grom->address + 1) & 0x1FFF) | (grom->address & 0xE000);
248   else
249      grom->address = (grom->address + 1) & 0xFFFF;
250}
251 
252/***************************************************************************
253    DEVICE FUNCTIONS
254***************************************************************************/
255 
256static DEVICE_START( ti99grom )
257{
258   ti99grom_state *grom = get_safe_token(device);
259   const ti99grom_config* gromconf = (const ti99grom_config*)get_config(device);
260 
261   grom->writable = gromconf->writeable;
262   grom->ident = gromconf->ident;
263   
264   grom->extended = (gromconf->size==0x1800)? TRUE : FALSE;
265 
266   grom->rollover = gromconf->rollover;
267 
268   devcb_write_line ready = DEVCB_LINE(gromconf->ready);
269   devcb_resolve_write_line(&grom->gromready, &ready, device);
270   // Test
271   // devcb_call_write_line(&grom->gromready, ASSERT_LINE);
272}
273 
274static DEVICE_STOP( ti99grom )
275{
276}
277 
278static DEVICE_RESET( ti99grom )
279{
280   const ti99grom_config* gromconf = (const ti99grom_config*)get_config(device);
281   ti99grom_state *grom = get_safe_token(device);
282   grom->address = 0;
283   grom->raddr_LSB = FALSE; 
284   grom->waddr_LSB = FALSE;
285   grom->buffer = 0;
286 
287   /* Try to get the pointer to the memory contents from the parent */
288   if (gromconf->region==NULL)
289      grom->memptr = (*gromconf->get_memory)(device->owner());
290   else
291      grom->memptr = memory_region(device->machine, gromconf->region);
292 
293   //  TODO: Check whether this may be 0 for console GROMs.
294   //   assert (grom->memptr!=NULL);
295 
296   grom->memptr += gromconf->offset;
297 
298   // TODO: If the GROM is a subdevice of another device, and a region
299   // is specified, we need to first determine the device tag and concatenate
300   // the GROM region behind this device tag; otherwise the region will not be
301   // found. May be done with an astring.
302}
303 
304static const char DEVTEMPLATE_SOURCE[] = __FILE__;
305 
306#define DEVTEMPLATE_ID(p,s)             p##ti99grom##s
307#define DEVTEMPLATE_FEATURES            DT_HAS_START | DT_HAS_STOP | DT_HAS_RESET | DT_HAS_INLINE_CONFIG
308#define DEVTEMPLATE_NAME                "tmc0430"
309#define DEVTEMPLATE_FAMILY              "TTL"
310#include "devtempl.h"
311 
312DEFINE_LEGACY_DEVICE( GROM, ti99grom );
src/mess/machine/ti99/gromport.c
r9488r9489
1/**********************************************************************
2
3    gromport.c
4
5*********************************************************************/
6
7#include "emu.h"
8#include "gromport.h"
9#include "devices/cartslot.h"
10#include "devices/multcart.h"
11#include "grom.h"
12
13typedef UINT8   (*read8z_device_func)  (ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, UINT8 *value);
14
15/* We set the number of slots to 8, although we may have up to 16. From a
16   logical point of view we could have 256, but the operating system only checks
17   the first 16 banks. */
18#define NUMBER_OF_CARTRIDGE_SLOTS 8
19
20typedef int assmfct(running_device *);
21
22DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_NONE, ti99_cartridge_pcb_none);
23DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_STD, ti99_cartridge_pcb_std);
24DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGED, ti99_cartridge_pcb_paged);
25DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_MINIMEM, ti99_cartridge_pcb_minimem);
26DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_SUPER, ti99_cartridge_pcb_super);
27DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_MBX, ti99_cartridge_pcb_mbx);
28DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGED379I, ti99_cartridge_pcb_paged379i);
29DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGEDCRU, ti99_cartridge_pcb_pagedcru);
30DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_GRAMKRACKER, ti99_cartridge_pcb_gramkracker);
31
32DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_NONE, ti99_cartridge_pcb_none);
33DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_STD, ti99_cartridge_pcb_std);
34DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGED, ti99_cartridge_pcb_paged);
35DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_MINIMEM, ti99_cartridge_pcb_minimem);
36DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_SUPER, ti99_cartridge_pcb_super);
37DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_MBX, ti99_cartridge_pcb_mbx);
38DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGED379I, ti99_cartridge_pcb_paged379i);
39DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGEDCRU, ti99_cartridge_pcb_pagedcru);
40DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_GRAMKRACKER, ti99_cartridge_pcb_gramkracker);
41
42/* Generic TI99 cartridge structure. */
43struct _cartridge_t
44{
45   // PCB device associated to this cartridge. If NULL, the slot is empty.
46   running_device *pcb;
47
48   // ROM page.
49   int rom_page;
50
51   // RAM page.
52   int ram_page;
53
54   // GROM buffer size.
55   int grom_size;
56   
57   // ROM buffer size. All banks have equal sizes.
58   int rom_size;
59   
60   // RAM buffer size. All banks have equal sizes.
61   int ram_size;
62
63   // GROM buffer.
64   UINT8 *grom_ptr;
65
66   // ROM buffer.
67   UINT8 *rom_ptr;
68
69   // ROM buffer for the second bank of paged cartridges.
70   UINT8 *rom2_ptr;
71
72   // RAM buffer. The persistence service is done by the cartridge system.
73   // The RAM space is a consecutive space; all banks are in one buffer.
74   UINT8 *ram_ptr;
75   
76   /* GK support. */
77   UINT16   grom_address;   
78   int      waddr_LSB;
79};
80typedef struct _cartridge_t cartridge_t;
81
82enum
83{
84   TI99CARTINFO_FCT_6000_R = DEVINFO_FCT_DEVICE_SPECIFIC,
85   TI99CARTINFO_FCT_6000_W,
86   TI99CARTINFO_FCT_CRU_R,
87   TI99CARTINFO_FCT_CRU_W,
88   TI99CART_FCT_ASSM,
89   TI99CART_FCT_DISASSM
90};
91
92typedef struct _ti99_multicart_state
93{
94   // Reserves space for all cartridges. This is also used in the legacy
95   // cartridge system, but only for slot 0.
96   cartridge_t cartridge[NUMBER_OF_CARTRIDGE_SLOTS];
97
98   // Determines which slot is currently active. This value is changed when
99   // there are accesses to other GROM base addresses.
100   int    active_slot;
101
102   // Used in order to enforce a special slot. This value is retrieved
103   // from the dipswitch setting. A value of -1 means automatic, that is,
104   // the grom base switch is used. Values 0 .. max refer to the
105   // respective slot.
106   int    fixed_slot;
107
108   // Holds the highest index of a cartridge being plugged in plus one.
109   // If we only have one cartridge inserted, we don't want to get a
110   // selection option, so we just mirror the memory contents.
111   int    next_free_slot;
112   
113   /* GK support. */
114   int      gk_slot;
115   int      gk_guest_slot;
116   
117   /* Legacy support. */
118   // Counts the number of slots which currently contain legacy format
119   // cartridge images.
120   int legacy_slots;
121
122   // Counts the number of slots which currently contain new format
123   // cartridge images.
124   int multi_slots;
125   
126   /* Used to cache the switch settings. */
127   UINT8 gk_switch[8];
128
129   /* Ready line */
130   devcb_resolved_write_line ready;
131   
132} ti99_multicart_state;
133
134#define AUTO -1
135
136/* Access to the pcb. Contained in the token of the pcb instance. */
137struct _ti99_pcb_t
138{
139   /* Read function for this cartridge. */
140   read8z_device_func read;
141
142   /* Write function for this cartridge. */
143   write8_device_func write;
144
145   /* Read function for this cartridge, CRU. */
146   read8z_device_func cruread;
147
148   /* Write function for this cartridge, CRU. */
149   write8_device_func cruwrite;
150
151   /* Link up to the cartridge structure which contains this pcb. */
152   cartridge_t *cartridge;
153
154   /* Function to assemble this cartridge. */
155   assmfct   *assemble;
156
157   /* Function to disassemble this cartridge. */
158   assmfct   *disassemble;
159   
160   /* Points to the (max 5) GROM devices. */
161   running_device *grom[5];
162};
163typedef struct _ti99_pcb_t ti99_pcb_t;
164
165INLINE ti99_multicart_state *get_safe_token(running_device *device)
166{
167   assert(device != NULL);
168   return (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
169}
170
171INLINE const ti99_multicart_config *get_config(running_device *device)
172{
173   assert(device != NULL);
174   assert(device->type() == TI99_MULTICART);
175   return (const ti99_multicart_config *) downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
176}
177
178INLINE ti99_pcb_t *get_safe_pcb_token(running_device *device)
179{
180   assert(device != NULL);
181   return (ti99_pcb_t *)downcast<legacy_device_base *>(device)->token();
182}
183
184static WRITE_LINE_DEVICE_HANDLER( cart_grom_ready )
185{
186   running_device *cartdev = device->owner()->owner();
187   ti99_multicart_state *cartslots = get_safe_token(cartdev);
188   devcb_call_write_line( &cartslots->ready, state );
189}
190
191/*
192   The console writes the values in this array to cache them.
193*/
194void set_gk_switches(running_device *cartsys, int number, int value)
195{
196   ti99_multicart_state *cartslots = get_safe_token(cartsys);
197   cartslots->gk_switch[number] = value;
198}
199
200static int get_gk_switch(running_device *cartsys, int number)
201{
202   ti99_multicart_state *cartslots = get_safe_token(cartsys);
203   return cartslots->gk_switch[number];
204}
205
206static int in_legacy_mode(running_device *device)
207{
208   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
209   return ((cartslots->legacy_slots>0) && (cartslots->multi_slots==0));
210}
211
212/*
213    Activates a slot in the multi-cartridge extender.
214*/
215static void cartridge_slot_set(running_device *cartsys, UINT8 slotnumber)
216{
217   ti99_multicart_state *cartslots = get_safe_token(cartsys);
218//  if (cartslots->active_slot != slotnumber) printf("Setting cartslot to %d\n", slotnumber);
219   if (cartslots->fixed_slot==AUTO)
220      cartslots->active_slot = slotnumber;
221   else
222      cartslots->active_slot = cartslots->fixed_slot;
223}
224
225static int slot_is_empty(running_device *cartsys, int slotnumber)
226{
227   cartridge_t *cart;
228   ti99_multicart_state *cartslots = get_safe_token(cartsys);
229
230   cart = &cartslots->cartridge[slotnumber];
231
232   if ((cart->rom_size==0) && (cart->ram_size==0) && (cart->grom_size==0))
233      return TRUE;
234   return FALSE;
235}
236
237static void clear_slot(running_device *cartsys, int slotnumber)
238{
239   cartridge_t *cart;
240   ti99_multicart_state *cartslots = get_safe_token(cartsys);
241
242   cart = &cartslots->cartridge[slotnumber];
243
244   cart->rom_size = cart->ram_size = cart->grom_size = 0;
245   cart->rom_ptr = NULL;
246   cart->rom2_ptr = NULL;
247   cart->ram_ptr = NULL;
248}
249
250/*
251    Find the index of the cartridge name. We assume the format
252    <name><number>, i.e. the number is the longest string from the right
253    which can be interpreted as a number.
254*/
255static int get_index_from_tagname(running_device *image)
256{
257   const char *tag = image->tag();
258   int maxlen = strlen(tag);
259   int i;
260   for (i=maxlen-1; i >=0; i--)
261      if (tag[i] < 48 || tag[i] > 57) break;
262
263   return atoi(tag+i+1);
264}
265
266/*
267    Common routine to assemble cartridges from resources.
268*/
269static cartridge_t *assemble_common(running_device *cartslot)
270{
271   /* Pointer to the cartridge structure. */
272   cartridge_t *cartridge;
273   running_device *cartsys = cartslot->owner();
274   ti99_multicart_state *cartslots = get_safe_token(cartsys);
275   running_device *pcb = cartslot->subdevice("pcb");
276   ti99_pcb_t *pcb_def;
277   
278   void *socketcont;
279   int reslength;
280//   int i;
281
282   int slotnumber = get_index_from_tagname(cartslot)-1;
283   assert(slotnumber>=0 && slotnumber<NUMBER_OF_CARTRIDGE_SLOTS);
284
285   /* There is a cartridge in this slot, check the maximum slot number. */
286   if (cartslots->next_free_slot <= slotnumber)
287   {
288      cartslots->next_free_slot = slotnumber+1;
289   }
290   cartridge = &cartslots->cartridge[slotnumber];
291
292   // Get the socket which is retrieved by the multicart instance in
293   // the state of the cartslot instance.
294   socketcont = cartslot_get_socket(cartslot, "grom_socket");
295   reslength = cartslot_get_resource_length(cartslot, "grom_socket");
296   if (socketcont != NULL)
297   {
298      cartridge->grom_ptr = (UINT8 *)socketcont;
299//      printf("grom_socket = %lx\n", cartridge->grom_ptr);
300      cartridge->grom_size = reslength;
301   }
302
303   socketcont = cartslot_get_socket(cartslot, "rom_socket");
304   reslength = cartslot_get_resource_length(cartslot, "rom_socket");
305   if (socketcont != NULL)
306   {
307      cartridge->rom_ptr = (UINT8 *)socketcont;
308      cartridge->rom_size = reslength;
309//      printf("set rom ptr = %lx, romlength = %04x, data = %02x %02x\n", cartridge->rom_ptr, cartridge->rom_size, cartridge->rom_ptr[0], cartridge->rom_ptr[1]);
310   }
311
312   socketcont = cartslot_get_socket(cartslot, "rom2_socket");
313//  reslength = cartslot_get_resource_length(cartslot, "rom2_socket");  /* cannot differ from rom_socket */
314   if (socketcont != NULL)
315   {
316      cartridge->rom2_ptr = (UINT8 *)socketcont;
317   }
318
319   socketcont = cartslot_get_socket(cartslot, "ram_socket");
320   reslength = cartslot_get_resource_length(cartslot, "ram_socket");
321   if (socketcont != NULL)
322   {
323      cartridge->ram_ptr = (UINT8 *)socketcont;
324      cartridge->ram_size = reslength;
325   }
326
327   // Register the GROMs
328   pcb_def = (ti99_pcb_t *)downcast<legacy_device_base *>(pcb)->token();
329   for (int i=0; i < 5; i++) pcb_def->grom[i]= NULL;
330   if (cartridge->grom_size > 0)      pcb_def->grom[0] = pcb->subdevice("grom_3");
331   if (cartridge->grom_size > 0x2000) pcb_def->grom[1] = pcb->subdevice("grom_4");
332   if (cartridge->grom_size > 0x4000) pcb_def->grom[2] = pcb->subdevice("grom_5");
333   if (cartridge->grom_size > 0x6000) pcb_def->grom[3] = pcb->subdevice("grom_6");
334   if (cartridge->grom_size > 0x8000) pcb_def->grom[4] = pcb->subdevice("grom_7");
335   
336   return cartridge;
337}
338
339static void set_pointers(running_device *pcb, int index)
340{
341   running_device *cartsys = pcb->owner()->owner();
342   ti99_multicart_state *cartslots = get_safe_token(cartsys);
343   ti99_pcb_t *pcb_def = (ti99_pcb_t *)downcast<legacy_device_base *>(pcb)->token();
344
345   pcb_def->read = (read8z_device_func)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CARTINFO_FCT_6000_R);
346   pcb_def->write = (write8_device_func)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CARTINFO_FCT_6000_W);
347   pcb_def->cruread = (read8z_device_func)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CARTINFO_FCT_CRU_R);
348   pcb_def->cruwrite = (write8_device_func)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CARTINFO_FCT_CRU_W);
349
350    pcb_def->assemble = (assmfct *)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CART_FCT_ASSM);
351    pcb_def->disassemble = (assmfct *)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CART_FCT_DISASSM);
352
353   pcb_def->cartridge = &cartslots->cartridge[index];
354   pcb_def->cartridge->pcb = pcb;
355}
356
357/*****************************************************************************
358  Cartridge type: None
359    This PCB device is just a pseudo device; the legacy mode is handled
360    by dedicated functions.
361******************************************************************************/
362static DEVICE_START(ti99_pcb_none)
363{
364   /* device is ti99_cartslot:cartridge:pcb */
365   set_pointers(device, get_index_from_tagname(device->owner())-1);
366}
367
368/*****************************************************************************
369  Cartridge type: Standard
370    Most cartridges are built in this type. Every cartridge may contain
371    GROM between 0 and 40 KiB, and ROM with 8 KiB length, no banking.
372******************************************************************************/
373
374static DEVICE_START(ti99_pcb_std)
375{
376   /* device is ti99_cartslot:cartridge:pcb */
377   set_pointers(device, get_index_from_tagname(device->owner())-1);
378}
379
380/*
381    Read handler for the CPU address space of the cartridge
382    Images for this area are found in the rom_sockets.
383*/
384static READ8Z_DEVICE_HANDLER( read_cart_std )
385{
386   /* device is pcb, owner is cartslot (cartridge is only a part of the state of cartslot) */
387   ti99_pcb_t *pcb = get_safe_pcb_token(device);
388   cartridge_t *cartridge = pcb->cartridge;
389   if (cartridge->rom_ptr!=NULL)
390   {
391      // For TI-99/8 we should plan for 16K cartridges. However, none was produced. Well, just ignore this thought,
392      *value = (cartridge->rom_ptr)[offset & 0x1fff]; 
393//      printf("read cartridge rom space (length %04x) %04x = %02x\n", cartridge->rom_size, offset, *value);
394   }
395}
396
397static WRITE8_DEVICE_HANDLER( write_cart_std )
398{
399   logerror("Write access to cartridge ROM at address %04x ignored\n", offset);
400}
401
402/*
403    The standard cartridge assemble routine. We just call the common
404    function here.
405*/
406static int assemble_std(running_device *image)
407{
408   assemble_common(image);
409   return IMAGE_INIT_PASS;
410}
411
412/*
413    Removes pointers and restores the state before plugging in the
414    cartridge.
415    The pointer to the location after the last cartridge is adjusted.
416    As it seems, we can use the same function for the disassembling of all
417    cartridge types.
418*/
419static int disassemble_std(running_device *image)
420{
421   int slotnumber;
422   int i;
423//   cartridge_t *cart;
424   running_device *cartsys = image->owner();
425   ti99_multicart_state *cartslots = get_safe_token(cartsys);
426
427   slotnumber = get_index_from_tagname(image)-1;
428
429   /* Search the highest remaining cartridge. */
430   cartslots->next_free_slot = 0;
431   for (i=NUMBER_OF_CARTRIDGE_SLOTS-1; i >= 0; i--)
432   {
433      if (i != slotnumber)
434      {
435         if (!slot_is_empty(cartsys, i))
436         {
437            cartslots->next_free_slot = i+1;
438            break;
439         }
440      }
441   }
442
443   clear_slot(cartsys, slotnumber);
444
445   return IMAGE_INIT_PASS;
446}
447
448/*****************************************************************************
449  Cartridge type: Paged (Extended Basic)
450    This cartridge consists of GROM memory and 2 pages of standard ROM.
451    The page is set by writing any value to a location in
452    the address area, where an even word offset sets the page to 0 and an
453    odd word offset sets the page to 1 (e.g. 6000 = bank 0, and
454    6002 = bank 1).
455******************************************************************************/
456
457static DEVICE_START(ti99_pcb_paged)
458{
459   /* device is ti99_cartslot:cartridge:pcb */
460   set_pointers(device, get_index_from_tagname(device->owner())-1);
461}
462
463/*
464    Read handler for the CPU address space of the cartridge
465    Images for this area are found in the rom_sockets.
466*/
467static READ8Z_DEVICE_HANDLER( read_cart_paged )
468{
469   /* device is pcb, owner is cartslot */
470   ti99_pcb_t *pcb = get_safe_pcb_token(device);
471   cartridge_t *cartridge = pcb->cartridge;
472   UINT8 *rombank;
473
474   if (cartridge->rom_page==0)
475      rombank = (UINT8*)cartridge->rom_ptr;
476   else
477      rombank = (UINT8*)cartridge->rom2_ptr;
478
479   if (rombank==NULL)
480   {
481      /* TODO: Check for consistency with the GROM memory handling. */
482      *value = 0;
483   }
484   else
485   {
486      *value = rombank[offset & 0x1fff];
487   }
488}
489
490/*
491    Handle paging. Extended Basic switches between ROM banks by
492    using the value of the LSB of the address where any value
493    is written to.
494*/
495static WRITE8_DEVICE_HANDLER( write_cart_paged )
496{
497   ti99_pcb_t *pcb = get_safe_pcb_token(device);
498   cartridge_t *cartridge = pcb->cartridge;
499   cartridge->rom_page = (offset >> 1) & 1;
500}
501
502/*
503    We require paged modules to have at least those two rom banks.
504*/
505static int assemble_paged(running_device *image)
506{
507   cartridge_t *cart;
508
509   cart = assemble_common(image);
510   if (cart->rom_ptr==NULL)
511   {
512      logerror("Missing ROM for paged cartridge");
513      return IMAGE_INIT_FAIL;
514   }
515   if (cart->rom2_ptr==NULL)
516   {
517      logerror("Missing second ROM for paged cartridge");
518      return IMAGE_INIT_FAIL;
519   }
520
521   return IMAGE_INIT_PASS;
522}
523
524/*****************************************************************************
525  Cartridge type: Mini Memory
526    GROM: 6 KiB (occupies G>6000 to G>7800)
527    ROM: 4 KiB (romfile is actually 8 K long, second half with zeros, 0x6000-0x6fff)
528    persistent RAM: 4 KiB (0x7000-0x7fff)
529******************************************************************************/
530
531static DEVICE_START(ti99_pcb_minimem)
532{
533   set_pointers(device, get_index_from_tagname(device->owner())-1);
534}
535
536static READ8Z_DEVICE_HANDLER( read_cart_minimem )
537{
538   /* device is pcb, owner is cartslot */
539   ti99_pcb_t *pcb = get_safe_pcb_token(device);
540   cartridge_t *cartridge = pcb->cartridge;
541
542   if ((offset & 0xf000)==0x6000)
543   {
544      *value = (cartridge->rom_ptr==NULL)? 0 : (cartridge->rom_ptr)[offset & 0x0fff];
545   }
546   else
547   {
548      *value = (cartridge->ram_ptr==NULL)? 0 : (cartridge->ram_ptr)[offset & 0x0fff];
549   }
550}
551
552/*
553    Mini Memory cartridge write operation. RAM is located at 0x7000.
554*/
555static WRITE8_DEVICE_HANDLER( write_cart_minimem )
556{
557   ti99_pcb_t *pcb = get_safe_pcb_token(device);
558   cartridge_t *cartridge = pcb->cartridge;
559
560   if (offset < 0x7000)
561   {
562      logerror("Write access to cartridge ROM at address %04x ignored", offset);
563   }
564   else
565   {
566      if (cartridge->ram_ptr==NULL)
567      {
568         logerror("No cartridge RAM at address %04x", offset);
569         /* TODO: Check for consistency with the GROM memory handling. */
570      }
571      else
572      {
573         (cartridge->ram_ptr)[offset-0x7000] = data;
574      }
575   }
576}
577
578static int assemble_minimem(running_device *image)
579{
580   cartridge_t *cart;
581
582   cart = assemble_common(image);
583   if (cart->grom_size==0)
584   {
585      logerror("Missing GROM for Mini Memory");
586      // should not fail here because there may be variations of
587      // cartridges which do not use all parts
588//      return IMAGE_INIT_FAIL;
589   }
590   if (cart->rom_size==0)
591   {
592      logerror("Missing ROM for Mini Memory");
593//      return IMAGE_INIT_FAIL;
594   }
595   if (cart->ram_size==0)
596   {
597      logerror("Missing RAM for Mini Memory");
598//      return IMAGE_INIT_FAIL;
599   }
600
601   return IMAGE_INIT_PASS;
602}
603
604/*****************************************************************************
605  Cartridge type: SuperSpace II
606    SuperSpace cartridge type. SuperSpace is intended as a user-definable
607    blank cartridge containing buffered RAM
608    It has an Editor/Assembler GROM which helps the user to load
609    the user program into the cartridge. If the user program has a suitable
610    header, the console recognizes the cartridge as runnable, and
611    assigns a number in the selection screen.
612    Switching the RAM banks in this cartridge is achieved by setting
613    CRU bits (the system serial interface).
614
615    GROM: Editor/Assembler GROM
616    ROM: none
617    persistent RAM: 32 KiB (0x6000-0x7fff, 4 banks)
618    Switching the bank is done via CRU write
619******************************************************************************/
620
621static DEVICE_START(ti99_pcb_super)
622{
623   set_pointers(device, get_index_from_tagname(device->owner())-1);
624}
625
626/*
627    The CRU read handler. The CRU is a serial interface in the console.
628    Using the CRU we can switch the banks in the SuperSpace cartridge.
629*/
630static READ8Z_DEVICE_HANDLER( read_cart_cru )
631{
632   ti99_pcb_t *pcb = get_safe_pcb_token(device);
633   cartridge_t *cartridge = pcb->cartridge;
634   // offset is the bit number. The CRU base address is already divided  by 2.
635
636   // ram_page contains the bank number. We have a maximum of
637   // 4 banks; the Super Space II manual says:
638   //
639   // Banks are selected by writing a bit pattern to CRU address >0800:
640   //
641   // Bank #   Value
642   // 0        >02  = 0000 0010
643   // 1        >08  = 0000 1000
644   // 2        >20  = 0010 0000
645   // 3        >80  = 1000 0000
646   //
647   // With the bank number (0, 1, 2, or 3) in R0:
648   //
649   // BNKSW   LI    R12,>0800   Set CRU address
650   //         LI    R1,2        Load Shift Bit
651   //         SLA   R0,1        Align Bank Number
652   //         JEQ   BNKS1       Skip shift if Bank 0
653   //         SLA   R1,0        Align Shift Bit
654   // BNKS1   LDCR  R1,0        Switch Banks
655   //         SRL   R0,1        Restore Bank Number (optional)
656   //         RT
657   printf("Superspace: CRU accessed at %04x\n", offset);
658   if ((offset & 1) == 0 || offset > 7)
659      *value = 0;
660
661   // CRU addresses are only 1 bit wide. Bytes are transferred from LSB
662   // to MSB. That is, 8 bit are eight consecutive addresses. */
663   *value = (cartridge->ram_page == (offset-1)/2);
664}
665
666static WRITE8_DEVICE_HANDLER( write_cart_cru )
667{
668   ti99_pcb_t *pcb = get_safe_pcb_token(device);
669   cartridge_t *cartridge = pcb->cartridge;
670   // data is bit
671   // offset is address
672   printf("Superspace: CRU accessed at %04x\n", offset);
673   if (offset < 8)
674   {
675      if (data != 0)
676         cartridge->ram_page = (offset-1)/2;
677   }
678}
679
680/*
681    SuperSpace RAM read operation. RAM is located at 0x6000 to 0x7fff
682    as 4 banks of 8 KiB each
683*/
684static READ8Z_DEVICE_HANDLER( read_cart_super )
685{
686   /* device is pcb, owner is cartslot */
687   ti99_pcb_t *pcb = get_safe_pcb_token(device);
688   cartridge_t *cartridge = pcb->cartridge;
689   offs_t boffset;
690
691   if (cartridge->ram_ptr==NULL)
692   {
693      *value = 0;
694   }
695   else
696   {
697      boffset = cartridge->ram_page * 0x2000 + (offset & 0x1fff);
698      *value = (cartridge->ram_ptr)[boffset];
699   }
700}
701
702/*
703    SuperSpace RAM write operation. RAM is located at 0x6000 to 0x7fff
704    as 4 banks of 8 KiB each
705*/
706static WRITE8_DEVICE_HANDLER( write_cart_super )
707{
708   ti99_pcb_t *pcb = get_safe_pcb_token(device);
709   cartridge_t *cartridge = pcb->cartridge;
710   offs_t boffset;
711
712   if (cartridge->ram_ptr==NULL)
713   {
714      logerror("No cartridge RAM at address %04x", offset);
715   }
716   else
717   {
718      boffset = cartridge->ram_page * 0x2000 + (offset & 0x1fff);
719      (cartridge->ram_ptr)[boffset] = data;
720   }
721}
722
723static int assemble_super(running_device *image)
724{
725   cartridge_t *cart;
726
727   cart = assemble_common(image);
728   if (cart->ram_size==0)
729   {
730      logerror("Missing RAM for SuperSpace");
731      return IMAGE_INIT_FAIL;
732   }
733   return IMAGE_INIT_PASS;
734}
735
736/*****************************************************************************
737  Cartridge type: MBX
738    GROM: up to 40 KiB
739    ROM: up to 16 KiB (in up to 2 banks of 8KiB each)
740    RAM: 1022 B (0x6c00-0x6ffd, overrides ROM in that area)
741    ROM mapper: 6ffe
742
743    Note that some MBX cartridges assume the presence of the MBX system
744    (additional console) and will not run without it. The MBX hardware is
745    not emulated yet.
746******************************************************************************/
747
748static DEVICE_START(ti99_pcb_mbx)
749{
750   set_pointers(device, get_index_from_tagname(device->owner())-1);
751}
752
753static READ8Z_DEVICE_HANDLER( read_cart_mbx )
754{
755   /* device is pcb, owner is cartslot */
756   ti99_pcb_t *pcb = get_safe_pcb_token(device);
757   cartridge_t *cartridge = pcb->cartridge;
758
759   if ((offset & 0x1c00)==0x0c00)
760   {
761      // This is the RAM area which overrides any ROM. There is no
762      // known banking behavior for the RAM, so we must assume that
763      // there is only one bank.
764      if (cartridge->ram_ptr != NULL)
765         *value = (cartridge->ram_ptr)[offset & 0x03ff];
766   }
767   else
768   {
769      if (cartridge->rom_ptr != NULL)
770         *value = (cartridge->rom_ptr)[(offset & 0x1fff)+ cartridge->rom_page*0x2000];
771   }
772}
773
774/*
775    MBX write operation.
776*/
777static WRITE8_DEVICE_HANDLER( write_cart_mbx )
778{
779   ti99_pcb_t *pcb = get_safe_pcb_token(device);
780   cartridge_t *cartridge = pcb->cartridge;
781
782   if (offset == 0x6ffe)
783   {
784      cartridge->rom_page = data & 1;
785      return;
786   }
787
788   if ((offset & 0x1c00)==0x0c00)
789   {
790      if (cartridge->ram_ptr == NULL)   return;
791      cartridge->ram_ptr[offset - 0x6c00] = data;
792   }
793}
794
795
796static int assemble_mbx(running_device *image)
797{
798   assemble_common(image);
799   return IMAGE_INIT_PASS;
800}
801
802/*****************************************************************************
803  Cartridge type: paged379i
804    This cartridge consists of one 16 KiB, 32 KiB, 64 KiB, or 128 KiB EEPROM
805    which is organised in 2, 4, 8, or 16 pages of 8 KiB each. The complete
806    memory contents must be stored in one dump file.
807    The pages are selected by writing a value to some memory locations. Due to
808    using the inverted outputs of the LS379 latch, setting the inputs of the
809    latch to all 0 selects the highest bank, while setting to all 1 selects the
810    lowest. There are some cartridges (16 KiB) which are using this scheme, and
811    there are new hardware developments mainly relying on this scheme.
812
813    Writing to       selects page (16K/32K/64K/128K)
814    >6000            1 / 3 / 7 / 15
815    >6002            0 / 2 / 6 / 14
816    >6004            1 / 1 / 5 / 13
817    >6006            0 / 0 / 4 / 12
818    >6008            1 / 3 / 3 / 11
819    >600A            0 / 2 / 2 / 10
820    >600C            1 / 1 / 1 / 9
821    >600E            0 / 0 / 0 / 8
822    >6010            1 / 3 / 7 / 7
823    >6012            0 / 2 / 6 / 6
824    >6014            1 / 1 / 5 / 5
825    >6016            0 / 0 / 4 / 4
826    >6018            1 / 3 / 3 / 3
827    >601A            0 / 2 / 2 / 2
828    >601C            1 / 1 / 1 / 1
829    >601E            0 / 0 / 0 / 0
830
831******************************************************************************/
832
833static DEVICE_START(ti99_pcb_paged379i)
834{
835   /* device is ti99_cartslot:cartridge:pcb */
836   set_pointers(device, get_index_from_tagname(device->owner())-1);
837}
838
839/*
840    Read handler for the CPU address space of the cartridge
841    Images for this area are found in the rom_sockets.
842*/
843static READ8Z_DEVICE_HANDLER( read_cart_paged379i )
844{
845   /* device is pcb, owner is cartslot */
846   ti99_pcb_t *pcb = get_safe_pcb_token(device);
847   cartridge_t *cartridge = pcb->cartridge;
848
849   if (cartridge->rom_ptr!=NULL)
850   {
851      *value = (cartridge->rom_ptr)[cartridge->rom_page*0x2000 + (offset & 0x1fff)];
852   }
853}
854
855/*
856   Determines which bank to set, depending on the size of the ROM. This is
857   some magic code that actually represents different PCB versions.
858*/
859static void set_paged379i_bank(cartridge_t *cartridge, int rompage)
860{
861   int mask = 0;
862   if (cartridge->rom_size > 16384)
863   {
864      if (cartridge->rom_size > 32768)
865      {
866         if (cartridge->rom_size > 65536)
867            mask = 15;
868         else
869            mask = 7;
870      }
871      else
872         mask = 3;
873   }
874   else
875      mask = 1;
876
877   cartridge->rom_page = rompage & mask;
878}
879
880/*
881    Handle paging. We use a LS379 latch for storing the page number. On this
882    PCB, the inverted output of the latch is used, so the order of pages
883    is reversed. (No problem as long as the memory dump is kept exactly
884    in the way it is stored in the EPROM.)
885    The latch can store a value of 4 bits. We adjust the number of
886    significant bits by the size of the memory dump (16K, 32K, 64K).
887*/
888static WRITE8_DEVICE_HANDLER( write_cart_paged379i )
889{
890   ti99_pcb_t *pcb = get_safe_pcb_token(device);
891   cartridge_t *cartridge = pcb->cartridge;
892
893   // Bits: 011x xxxx xxxb bbbx
894   // x = don't care, bbbb = bank
895   set_paged379i_bank(cartridge, 15 - ((offset>>1) & 15));
896}
897
898/*
899    Paged379i modules have one EPROM dump.
900*/
901static int assemble_paged379i(running_device *image)
902{
903   cartridge_t *cart;
904
905   cart = assemble_common(image);
906   if (cart->rom_ptr==NULL)
907   {
908      logerror("Missing ROM for paged cartridge");
909      return IMAGE_INIT_FAIL;
910   }
911   set_paged379i_bank(cart, 15);
912   return IMAGE_INIT_PASS;
913}
914
915/*****************************************************************************
916  Cartridge type: pagedcru
917    This cartridge consists of one 16 KiB, 32 KiB, or 64 KiB EEPROM which is
918    organised in 2, 4, or 8 pages of 8 KiB each. We assume there is only one
919    dump file of the respective size.
920    The pages are selected by writing a value to the CRU. This scheme is
921    similar to the one used for the SuperSpace cartridge, with the exception
922    that we are using ROM only, and we can have up to 8 pages.
923
924    Bank     Value written to CRU>0800
925    0      >0002  = 0000 0000 0000 0010
926    1      >0008  = 0000 0000 0000 1000
927    2      >0020  = 0000 0000 0010 0000
928    3      >0080  = 0000 0000 1000 0000
929    4      >0200  = 0000 0010 0000 0000
930    5      >0800  = 0000 1000 0000 0000
931    6      >2000  = 0010 0000 0000 0000
932    7      >8000  = 1000 0000 0000 0000
933
934******************************************************************************/
935
936static DEVICE_START(ti99_pcb_pagedcru)
937{
938   /* device is ti99_cartslot:cartridge:pcb */
939   set_pointers(device, get_index_from_tagname(device->owner())-1);
940}
941
942/*
943    Read handler for the CPU address space of the cartridge
944    Images for this area are found in the rom_sockets.
945*/
946static READ8Z_DEVICE_HANDLER( read_cart_pagedcru )
947{
948   /* device is pcb, owner is cartslot */
949   ti99_pcb_t *pcb = get_safe_pcb_token(device);
950   cartridge_t *cartridge = pcb->cartridge;
951
952   if (cartridge->rom_ptr!=NULL)
953   {
954      *value = (cartridge->rom_ptr)[cartridge->rom_page*0x2000 + (offset & 0x1fff)];
955   }
956}
957
958/*
959    This type of cartridge does not support writing to the EPROM address
960    space.
961*/
962static WRITE8_DEVICE_HANDLER( write_cart_pagedcru )
963{
964   return;
965}
966
967/*
968    The CRU read handler. The CRU is a serial interface in the console.
969    Using the CRU we can switch the banks in the SuperSpace cartridge.
970    For documentation see the corresponding cru function above. Note we are
971    using rom_page here.
972*/
973static READ8Z_DEVICE_HANDLER( read_cart_cru_paged )
974{
975   ti99_pcb_t *pcb = get_safe_pcb_token(device);
976   cartridge_t *cartridge = pcb->cartridge;
977
978   int page = cartridge->rom_page;
979   if ((offset & 0xf800)==0x0800)
980   {
981      int bit = (offset & 0x001e)/2;
982      if (bit != 0)
983      {
984         page = page-(bit/2);  // 4 page flags per 8 bits
985      }     
986      *value = 1 << (page*2+1);
987   }
988}
989
990static WRITE8_DEVICE_HANDLER( write_cart_cru_paged )
991{
992   ti99_pcb_t *pcb = get_safe_pcb_token(device);
993   cartridge_t *cartridge = pcb->cartridge;
994
995   if ((offset & 0xf800)==0x0800)
996   {
997      int bit = (offset & 0x001e)/2;
998      if (data != 0 && bit > 0)
999      {
1000         cartridge->rom_page = (bit-1)/2;
1001      }
1002   }
1003}
1004
1005/*
1006    Pagedcru modules have one EPROM dump.
1007*/
1008static int assemble_pagedcru(running_device *image)
1009{
1010   cartridge_t *cart;
1011
1012   cart = assemble_common(image);
1013   if (cart->rom_ptr==NULL)
1014   {
1015      logerror("Missing ROM for pagedcru cartridge");
1016      return IMAGE_INIT_FAIL;
1017   }
1018   cart->rom_page = 0;
1019   return IMAGE_INIT_PASS;
1020}
1021
1022/*****************************************************************************
1023  Cartridge type: gramkracker
1024******************************************************************************/
1025
1026static DEVICE_START(ti99_pcb_gramkracker)
1027{
1028   /* device is ti99_cartslot:cartridge:pcb */
1029//  printf("DEVICE_START(ti99_pcb_pagedcru), tag of device=%s\n", device->tag());
1030   set_pointers(device, get_index_from_tagname(device->owner())-1);
1031}
1032
1033/*
1034    The GRAM Kracker contains one GROM and several buffered RAM chips
1035*/
1036static int assemble_gramkracker(running_device *image)
1037{
1038   cartridge_t *cart;
1039   int id,i;
1040
1041   running_device *cartsys = image->owner();
1042   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1043
1044   cart = assemble_common(image);
1045
1046   if (cart->grom_ptr==NULL)
1047   {
1048      logerror("Missing loader GROM for GRAM Kracker system");
1049      return IMAGE_INIT_FAIL;
1050   }
1051
1052   if (cart->ram_size < 81920)
1053   {
1054      logerror("Missing or insufficient RAM for GRAM Kracker system");
1055      return IMAGE_INIT_FAIL;
1056   }
1057
1058   // Get slot number
1059   id = get_index_from_tagname(image);
1060   cartslots->gk_slot = id-1;
1061   cartslots->gk_guest_slot = -1;
1062   // The first cartridge that is still plugged in is the "guest" of the
1063   // GRAM Kracker
1064   for (i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++)
1065   {
1066      if (!slot_is_empty(cartsys, i) && (i != cartslots->gk_slot))
1067      {
1068         cartslots->gk_guest_slot = i;
1069         break;
1070      }
1071   }
1072   return IMAGE_INIT_PASS;
1073}
1074
1075/*
1076    Unplugs the GRAM Kracker. The "guest" is still plugged in, but will be
1077    treated as normal.
1078*/
1079static int disassemble_gramkracker(running_device *cartslot)
1080{
1081   running_device *cartsys = cartslot->owner();
1082   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1083
1084   int slotnumber = get_index_from_tagname(cartslot)-1;
1085   assert(slotnumber>=0 && slotnumber<NUMBER_OF_CARTRIDGE_SLOTS);
1086
1087   cartslots->gk_slot = -1;
1088   cartslots->gk_guest_slot = -1;
1089
1090   return disassemble_std(cartslot);
1091}
1092
1093
1094/*****************************************************************************
1095  Device metadata
1096******************************************************************************/
1097
1098/*
1099   Get the pointer to the GROM data from the cartridge. Called by the GROM.
1100*/
1101static UINT8 *get_grom_ptr(running_device *device)
1102{
1103   ti99_pcb_t *pcb = get_safe_pcb_token(device);
1104   return pcb->cartridge->grom_ptr;
1105}
1106
1107static MACHINE_CONFIG_FRAGMENT(ti99_cart_common)
1108   MDRV_GROM_ADD_P( "grom_3", 3, get_grom_ptr, 0x0000, 0x1800, cart_grom_ready )
1109   MDRV_GROM_ADD_P( "grom_4", 4, get_grom_ptr, 0x2000, 0x1800, cart_grom_ready )
1110   MDRV_GROM_ADD_P( "grom_5", 5, get_grom_ptr, 0x4000, 0x1800, cart_grom_ready )
1111   MDRV_GROM_ADD_P( "grom_6", 6, get_grom_ptr, 0x6000, 0x1800, cart_grom_ready )
1112   MDRV_GROM_ADD_P( "grom_7", 7, get_grom_ptr, 0x8000, 0x1800, cart_grom_ready )
1113MACHINE_CONFIG_END
1114
1115static DEVICE_GET_INFO(ti99_cart_common)
1116{
1117   switch(state)
1118   {
1119      /* --- the following bits of info are returned as 64-bit signed integers --- */
1120      case DEVINFO_INT_TOKEN_BYTES:
1121         info->i = sizeof(ti99_pcb_t);
1122         break;
1123      case DEVINFO_INT_INLINE_CONFIG_BYTES:
1124         info->i = 0;
1125         break;
1126         
1127      case DEVINFO_PTR_MACHINE_CONFIG:     
1128         info->machine_config = MACHINE_CONFIG_NAME(ti99_cart_common);
1129         break;
1130
1131      /* --- the following bits of info are returned as pointers to functions --- */
1132      case DEVINFO_FCT_START:
1133         info->start = DEVICE_START_NAME(ti99_pcb_std);
1134         break;
1135      case DEVINFO_FCT_STOP:
1136         /* Nothing */
1137         break;
1138      case DEVINFO_FCT_RESET:
1139         /* Nothing */
1140         break;
1141      case TI99CARTINFO_FCT_6000_R:
1142         info->f = (genf *) read_cart_std; break;
1143
1144      case TI99CARTINFO_FCT_6000_W:
1145         info->f = (genf *) write_cart_std; break;
1146
1147      case TI99CARTINFO_FCT_CRU_R:
1148         /* Nothing */
1149         break;
1150
1151      case TI99CARTINFO_FCT_CRU_W:
1152         /* Nothing */
1153         break;
1154
1155      case TI99CART_FCT_ASSM:
1156         info->f = (genf *) assemble_std;
1157         break;
1158
1159      case TI99CART_FCT_DISASSM:
1160         info->f = (genf *) disassemble_std;
1161         break;
1162
1163      /* --- the following bits of info are returned as NULL-terminated strings --- */
1164      case DEVINFO_STR_NAME:
1165         strcpy(info->s, "TI99 standard cartridge pcb");
1166         break;
1167      case DEVINFO_STR_FAMILY:
1168         strcpy(info->s, "TI99 cartridge pcb");
1169         break;
1170      case DEVINFO_STR_VERSION:
1171         strcpy(info->s, "1.0");
1172         break;
1173      case DEVINFO_STR_SOURCE_FILE:
1174         strcpy(info->s, __FILE__);
1175         break;
1176      case DEVINFO_STR_CREDITS:
1177         /* Nothing */
1178         break;
1179   }
1180}
1181
1182DEVICE_GET_INFO(ti99_cartridge_pcb_none)
1183{
1184   switch(state)
1185   {
1186      case DEVINFO_FCT_START:
1187         info->start = DEVICE_START_NAME(ti99_pcb_none);
1188         break;
1189
1190      case DEVINFO_STR_NAME:
1191         strcpy(info->s, "TI99 empty cartridge");
1192         break;
1193
1194      // Don't create GROMs
1195      case DEVINFO_PTR_MACHINE_CONFIG:     
1196         break;
1197         
1198      default:
1199         DEVICE_GET_INFO_CALL(ti99_cart_common);
1200         break;
1201   }
1202}
1203
1204DEVICE_GET_INFO(ti99_cartridge_pcb_std)
1205{
1206   DEVICE_GET_INFO_CALL(ti99_cart_common);
1207}
1208
1209DEVICE_GET_INFO(ti99_cartridge_pcb_paged)
1210{
1211   switch(state)
1212   {
1213      case DEVINFO_FCT_START:
1214         info->start = DEVICE_START_NAME(ti99_pcb_paged);
1215         break;
1216
1217      case TI99CART_FCT_ASSM:
1218         info->f = (genf *) assemble_paged;
1219         break;
1220
1221      case TI99CARTINFO_FCT_6000_R:
1222         info->f = (genf *) read_cart_paged;
1223         break;
1224
1225      case TI99CARTINFO_FCT_6000_W:
1226         info->f = (genf *) write_cart_paged;
1227         break;
1228
1229      case DEVINFO_STR_NAME:
1230         strcpy(info->s, "TI99 paged cartridge pcb");
1231         break;
1232
1233      default:
1234         DEVICE_GET_INFO_CALL(ti99_cart_common);
1235         break;
1236   }
1237}
1238
1239DEVICE_GET_INFO(ti99_cartridge_pcb_minimem)
1240{
1241   switch(state)
1242   {
1243      case DEVINFO_FCT_START:
1244         info->start = DEVICE_START_NAME(ti99_pcb_minimem);
1245         break;
1246
1247      case TI99CART_FCT_ASSM:
1248         info->f = (genf *) assemble_minimem;
1249         break;
1250      case TI99CARTINFO_FCT_6000_R:
1251         info->f = (genf *) read_cart_minimem;
1252         break;
1253      case TI99CARTINFO_FCT_6000_W:
1254         info->f = (genf *) write_cart_minimem;
1255         break;
1256         
1257      case DEVINFO_STR_NAME:
1258         strcpy(info->s, "TI99 MiniMemory cartridge pcb");
1259         break;
1260
1261      default:
1262         DEVICE_GET_INFO_CALL(ti99_cart_common);
1263         break;
1264   }
1265}
1266
1267DEVICE_GET_INFO(ti99_cartridge_pcb_super)
1268{
1269   switch(state)
1270   {
1271      case DEVINFO_FCT_START:
1272         info->start = DEVICE_START_NAME(ti99_pcb_super);
1273         break;
1274
1275      case TI99CART_FCT_ASSM:
1276         info->f = (genf *) assemble_super;
1277         break;
1278      case TI99CARTINFO_FCT_6000_R:
1279         info->f = (genf *) read_cart_super;
1280         break;
1281      case TI99CARTINFO_FCT_6000_W:
1282         info->f = (genf *) write_cart_super;
1283         break;
1284      case TI99CARTINFO_FCT_CRU_R:
1285         info->f = (genf *) read_cart_cru;
1286         break;
1287      case TI99CARTINFO_FCT_CRU_W:
1288         info->f = (genf *) write_cart_cru;
1289         break;
1290
1291      // Don't create GROMs
1292      case DEVINFO_PTR_MACHINE_CONFIG:     
1293         break;
1294
1295      case DEVINFO_STR_NAME:
1296         strcpy(info->s, "TI99 SuperSpace cartridge pcb");
1297         break;
1298
1299      default:
1300         DEVICE_GET_INFO_CALL(ti99_cart_common);
1301         break;
1302   }
1303}
1304
1305DEVICE_GET_INFO(ti99_cartridge_pcb_mbx)
1306{
1307   switch(state)
1308   {
1309      case DEVINFO_FCT_START:
1310         info->start = DEVICE_START_NAME(ti99_pcb_mbx);
1311         break;
1312
1313      case TI99CART_FCT_ASSM:
1314         info->f = (genf *) assemble_mbx;
1315         break;
1316      case TI99CARTINFO_FCT_6000_R:
1317         info->f = (genf *) read_cart_mbx;
1318         break;
1319      case TI99CARTINFO_FCT_6000_W:
1320         info->f = (genf *) write_cart_mbx;
1321         break;
1322
1323      case DEVINFO_STR_NAME:
1324         strcpy(info->s, "TI99 MBX cartridge pcb");
1325         break;
1326
1327      default:
1328         DEVICE_GET_INFO_CALL(ti99_cart_common);
1329         break;
1330   }
1331}
1332
1333DEVICE_GET_INFO(ti99_cartridge_pcb_paged379i)
1334{
1335   switch(state)
1336   {
1337      case DEVINFO_FCT_START:
1338         info->start = DEVICE_START_NAME(ti99_pcb_paged379i);
1339         break;
1340
1341      case TI99CART_FCT_ASSM:
1342         info->f = (genf *) assemble_paged379i; break;
1343
1344      case TI99CARTINFO_FCT_6000_R:
1345         info->f = (genf *) read_cart_paged379i;
1346         break;
1347
1348      case TI99CARTINFO_FCT_6000_W:
1349         info->f = (genf *) write_cart_paged379i;
1350         break;
1351
1352      case DEVINFO_STR_NAME:
1353         strcpy(info->s, "TI99 paged379i cartridge pcb");
1354         break;
1355
1356      default:
1357         DEVICE_GET_INFO_CALL(ti99_cart_common);
1358         break;
1359   }
1360}
1361
1362DEVICE_GET_INFO(ti99_cartridge_pcb_pagedcru)
1363{
1364   switch(state)
1365   {
1366      case DEVINFO_FCT_START:
1367         info->start = DEVICE_START_NAME(ti99_pcb_pagedcru);
1368         break;
1369
1370      case TI99CART_FCT_ASSM:
1371         info->f = (genf *) assemble_pagedcru;
1372         break;
1373
1374      case TI99CARTINFO_FCT_6000_R:
1375         info->f = (genf *) read_cart_pagedcru;
1376         break;
1377
1378      case TI99CARTINFO_FCT_6000_W:
1379         info->f = (genf *) write_cart_pagedcru;
1380         break;
1381
1382      case TI99CARTINFO_FCT_CRU_R:
1383         info->f = (genf *) read_cart_cru_paged;
1384         break;
1385      case TI99CARTINFO_FCT_CRU_W:
1386         info->f = (genf *) write_cart_cru_paged;
1387         break;
1388
1389      case DEVINFO_STR_NAME:
1390         strcpy(info->s, "TI99 pagedcru cartridge pcb");
1391         break;
1392
1393      default:
1394         DEVICE_GET_INFO_CALL(ti99_cart_common);
1395         break;
1396   }
1397}
1398
1399DEVICE_GET_INFO(ti99_cartridge_pcb_gramkracker)
1400{
1401   switch(state)
1402   {
1403      case DEVINFO_FCT_START:
1404         info->start = DEVICE_START_NAME(ti99_pcb_gramkracker);
1405         break;
1406
1407      case TI99CART_FCT_ASSM:
1408         info->f = (genf *) assemble_gramkracker;
1409         break;
1410
1411      case TI99CART_FCT_DISASSM:
1412         info->f = (genf *) disassemble_gramkracker;
1413         break;
1414
1415      case DEVINFO_STR_NAME:
1416         strcpy(info->s, "TI99 GRAM Kracker system");
1417         break;
1418
1419      default:
1420         DEVICE_GET_INFO_CALL(ti99_cart_common);
1421         break;
1422   }
1423}
1424
1425/*****************************************************************************
1426  The cartridge handling of the multi-cartridge system.
1427  Every cartridge contains a PCB device. The memory handlers delegate the calls
1428  to the respective handlers of the cartridges.
1429******************************************************************************/
1430/*
1431    Initialize a cartridge. Each cartridge contains a PCB device.
1432*/
1433static DEVICE_START( ti99_cartridge )
1434{
1435   cartslot_t *cart = (cartslot_t *)downcast<legacy_device_base *>(device)->token();
1436
1437   /* find the PCB device */
1438   cart->pcb_device = device->subdevice(TAG_PCB);
1439}
1440
1441/*
1442    Load the cartridge image files. Apart from reading, we set pointers
1443    to the image files so that during runtime we do not need search
1444    operations.
1445*/
1446static DEVICE_IMAGE_LOAD( ti99_cartridge )
1447{
1448   running_device *pcbdev = cartslot_get_pcb(&image.device());
1449//   running_device *cartsys = image.device().owner();
1450//   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1451
1452   int result;
1453
1454   if (pcbdev != NULL)
1455   {
1456      /* If we are here, we have a multicart. */
1457      ti99_pcb_t *pcb = (ti99_pcb_t *)downcast<legacy_device_base *>(pcbdev)->token();
1458      cartslot_t *cart = (cartslot_t *)downcast<legacy_device_base *>(&image.device())->token();
1459
1460      /* try opening this as a multicart */
1461      // This line requires that cartslot_t be included in cartslot.h,
1462      // otherwise one cannot make use of multicart handling within such a
1463      // custom LOAD function.
1464      multicart_open_error me = multicart_open(image.filename(), image.device().machine->gamedrv->name, MULTICART_FLAGS_LOAD_RESOURCES, &cart->mc);
1465
1466      // Now that we have loaded the image files, let the PCB put them all
1467      // together. This means we put the images in a structure which allows
1468      // for a quick access by the memory handlers. Every PCB defines an
1469      // own assembly method.
1470      if (me == MCERR_NONE)
1471         result = pcb->assemble(image);
1472      else
1473         fatalerror("Error loading multicart: %s", multicart_error_text(me));
1474   }
1475   else
1476   {
1477      fatalerror("Error loading multicart: no pcb found.");
1478   }
1479   return result;
1480}
1481
1482/*
1483    This is called when the cartridge is unplugged (or the emulator is
1484    stopped).
1485*/
1486static DEVICE_IMAGE_UNLOAD( ti99_cartridge )
1487{
1488   running_device *pcbdev;
1489//   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(image.device().owner())->token();
1490
1491   if (downcast<legacy_device_base *>(&image.device())->token() == NULL)
1492   {
1493      // This means something went wrong during the pcb
1494      // identification (e.g. one of the cartridge files was not
1495      // found). We do not need to (and cannot) unload the cartridge.
1496      return;
1497   }
1498   pcbdev = cartslot_get_pcb(image);
1499
1500   if (pcbdev != NULL)
1501   {
1502      ti99_pcb_t *pcb = (ti99_pcb_t *)downcast<legacy_device_base *>(pcbdev)->token();
1503      cartslot_t *cart = (cartslot_t *)downcast<legacy_device_base *>(&image.device())->token();
1504
1505      if (cart->mc != NULL)
1506      {
1507         /* Remove pointers and de-big-endianize RAM contents. */
1508         pcb->disassemble(image);
1509
1510         // Close the multicart; all RAM resources will be
1511         // written to disk
1512         multicart_close(cart->mc);
1513         cart->mc = NULL;
1514
1515      }
1516   }
1517}
1518
1519/*****************************************************************************
1520  The overall multi-cartridge slot system. It contains instances of
1521  cartridges which contain PCB devices. The memory handlers delegate the calls
1522  to the respective handlers of the cartridges.
1523
1524  Note that the term "multi-cartridge system" and "multicart" are not the same:
1525  A "multicart" may contain multiple resources, organized on a PCB. The multi-
1526  cart system may thus host multiple multicarts.
1527
1528  Actually, the name of the device should be changed (however, the device name
1529  length is limited)
1530******************************************************************************/
1531
1532static READ8Z_DEVICE_HANDLER( ti99_cart_gk_rz );
1533static WRITE8_DEVICE_HANDLER( ti99_cart_gk_w );
1534static void cartridge_gram_kracker_writeg(running_device *cartsys, int offset, UINT8 data);
1535static void cartridge_gram_kracker_readg(running_device *device, UINT8 *value);
1536static READ8Z_DEVICE_HANDLER( ti99_cart_cru_gk_rz );
1537static WRITE8_DEVICE_HANDLER( ti99_cart_cru_gk_w );
1538
1539/*
1540    Instantiation of a multicart system for the TI family.
1541*/
1542static DEVICE_START(ti99_multicart)
1543{
1544   int i;
1545   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1546   const ti99_multicart_config* cartconf = (const ti99_multicart_config*)get_config(device);
1547
1548   cartslots->active_slot = 0;
1549   cartslots->next_free_slot = 0;
1550
1551   for (i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++)
1552   {
1553      cartslots->cartridge[i].pcb = NULL;
1554      clear_slot(device, i);
1555   }
1556   
1557   devcb_write_line ready = DEVCB_LINE(cartconf->ready);
1558
1559   devcb_resolve_write_line(&cartslots->ready, &ready, device);
1560   
1561   // The cartslot system is initialized now. The cartridges themselves
1562   // need to check whether their parts are available.
1563}
1564
1565static DEVICE_STOP(ti99_multicart)
1566{
1567//  printf("DEVICE_STOP(ti99_multicart)\n");
1568}
1569
1570static DEVICE_RESET(ti99_multicart)
1571{
1572   // Consider to propagate RESET to cartridges.
1573   // However, schematics do not reveal any pin for resetting a cartridge;
1574   // the reset line is an input used when plugging in a cartridge.
1575
1576   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1577   int slotnumber = input_port_read(device->machine, "CARTSLOT");
1578   cartslots->fixed_slot = slotnumber-1; /* auto = -1 */
1579}
1580
1581/*
1582    Accesses the ROM regions of the cartridge for reading.
1583*/
1584READ8Z_DEVICE_HANDLER( gromportr_rz )
1585{
1586   ti99_multicart_state *cartslots = (ti99_multicart_state *) downcast<legacy_device_base *>(device)->token();
1587   int slot = cartslots->active_slot;
1588   cartridge_t *cart;
1589
1590   // Handle GRAM Kracker
1591   // We could also consider to use a flag, but input_port_read uses
1592   // a hashtable, so this should not be too slow
1593   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1594   {
1595      ti99_cart_gk_rz(device, offset, value);
1596      return;
1597   }
1598   
1599   /* Sanity check. Higher slots are always empty. */
1600   if (slot >= NUMBER_OF_CARTRIDGE_SLOTS)
1601      return;
1602
1603   // Same as above (GROM read)
1604   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1605      slot=0;
1606
1607   cart = &cartslots->cartridge[slot];
1608
1609   if (!slot_is_empty(device, slot))
1610   {
1611//      printf("try it on slot %d\n", slot);
1612      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cart->pcb)->token();
1613      (*pcbdef->read)(cart->pcb, offset, value);
1614   }
1615}
1616
1617/*
1618    Accesses the ROM regions of the cartridge for writing.
1619*/
1620WRITE8_DEVICE_HANDLER( gromportr_w )
1621{
1622   ti99_multicart_state *cartslots = (ti99_multicart_state *) downcast<legacy_device_base *>(device)->token();
1623   int slot = cartslots->active_slot;
1624   cartridge_t *cart;
1625
1626   // Handle GRAM Kracker
1627   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1628      ti99_cart_gk_w(device, offset, data);
1629
1630   /* Sanity check. Higher slots are always empty. */
1631   if (slot >= NUMBER_OF_CARTRIDGE_SLOTS)
1632      return;
1633
1634   /* Same as above (READ16). */
1635   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1636      slot=0;
1637
1638   cart = &cartslots->cartridge[slot];
1639
1640   if (!slot_is_empty(device, slot))
1641   {
1642      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cart->pcb)->token();
1643      (*pcbdef->write)(cart->pcb, offset, data);
1644   }
1645}
1646
1647/*
1648    Set the address pointer value or write to GRAM (if available).
1649*/
1650WRITE8_DEVICE_HANDLER(gromportg_w)
1651{
1652   int slot;
1653   cartridge_t *cartridge;
1654   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1655
1656   // Set the cart slot.
1657   // 1001 1wbb bbbb bbr0
1658
1659   cartridge_slot_set(device, (UINT8)((offset>>2) & 0x00ff));
1660   slot = cartslots->active_slot;
1661
1662   // The selection mechanism of the console checks the different GROM address
1663   // bases, and when it finds different data, it concludes that there is
1664   // indeed a multi-cartridge facility. Empty   slots return 0 at all
1665   // addresses.
1666   // Unfortunately, TI's cartridge selection mechanism has an undesirable
1667   // side-effect which we work around in this implementation.
1668   // When we have only one cartridge we would like to get only the option to
1669   // select this cartridge and not an option to switch to the next one (which
1670   // would immediately cycle back to cartridge 1). However, the console
1671   // routines always show the switch option when any two slots have different
1672   // content, and this is the case with only one cartridge (slot 2 will then
1673   // be filled with zeros).
1674   // So if next_free_slot==1, we have one cartridge in slot 0.
1675   // In that case we trick the OS to believe that the addressed
1676   // cartridge appears at all locations which causes it to assume a
1677   // standard single cartslot.
1678
1679   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1680      slot=0;
1681
1682   // Handle the GRAM Kracker
1683   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1684   {
1685      cartridge_gram_kracker_writeg(device, offset, data);
1686      return;
1687   }
1688
1689   if (slot < NUMBER_OF_CARTRIDGE_SLOTS)
1690   {
1691      cartridge = &cartslots->cartridge[slot];
1692      // Send the request to all mounted GROMs
1693      if (cartridge->pcb!=NULL)
1694      {
1695         for (int i=0; i < 5; i++)
1696         {
1697            ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cartridge->pcb)->token();
1698            if (pcbdef->grom[i]!=NULL)
1699               ti99grom_w(pcbdef->grom[i], offset, data);
1700         }
1701      }
1702   }
1703}
1704
1705/*
1706    GROM access. Nota bene: We only react to the request if there is a GROM
1707    at the selected bank with the currently selected ID. If not, just do
1708    nothing; do not return a value.
1709    (We must not return a value since all GROMs are connected in parallel, so
1710    returning a 0, for instance, will spoil the processing of other GROMs.)
1711*/
1712READ8Z_DEVICE_HANDLER(gromportg_rz)
1713{
1714   int slot;
1715   cartridge_t *cartridge;
1716   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1717
1718   // Set the cart slot. Note that the port must be adjusted for 16-bit
1719   // systems, i.e. it should be shifted left by 1.
1720   // 1001 1wbb bbbb bbr0
1721
1722   cartridge_slot_set(device, (UINT8)((offset>>2) & 0x00ff));
1723   
1724   // Handle the GRAM Kracker
1725   // BTW, the GK does not have a readable address counter, but the console
1726   // GROMs will keep our addess counter up to date. That is
1727   // exactly what happens in the real machine.
1728   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1729   {
1730      if ((offset & 0x0002)==0) cartridge_gram_kracker_readg(device, value);
1731      return;
1732   }
1733
1734   slot = cartslots->active_slot;
1735   
1736   // This fixes a minor issue: The selection mechanism of the console
1737   // concludes that there are multiple cartridges plugged in when it
1738   // checks the different GROM bases and finds different data. Empty
1739   // slots should return 0 at all addresses, but when we have only
1740   // one cartridge, this entails that the second cartridge is
1741   // different (all zeros), and so we get a meaningless selection
1742   // option between cartridge 1 and 1 and 1 ...
1743   //
1744   // So if next_free_slot==1, we have one cartridge in slot 0.
1745   // In that case we trick the OS to believe that the addressed
1746   // cartridge appears at all locations which causes it to assume a
1747   // standard single cartslot.
1748   
1749   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1750      slot=0;
1751   
1752   if (slot < NUMBER_OF_CARTRIDGE_SLOTS)
1753   {
1754      // Select the cartridge which the multicart system is currently pointing at
1755      cartridge = &cartslots->cartridge[slot];
1756      // Send the request to all mounted GROMs on this PCB
1757      if (cartridge->pcb!=NULL)
1758      {
1759         for (int i=0; i < 5; i++)
1760         {
1761            ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cartridge->pcb)->token();
1762            if (pcbdef->grom[i]!=NULL)
1763               ti99grom_rz(pcbdef->grom[i], offset, value);
1764         }
1765      }
1766   }
1767}
1768
1769/*
1770    CRU interface to cartridges, used only by SuperSpace and Pagedcru
1771    style cartridges.
1772    The SuperSpace has a CRU-based memory mapper. It is accessed via the
1773    cartridge slot on CRU base >0800.
1774*/
1775READ8Z_DEVICE_HANDLER( gromportc_rz )
1776{
1777   ti99_multicart_state *cartslots = (ti99_multicart_state *) downcast<legacy_device_base *>(device)->token();
1778   cartridge_t *cart;
1779
1780   int slot = cartslots->active_slot;
1781
1782   // Handle GRAM Kracker
1783   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1784   {
1785      ti99_cart_cru_gk_rz(device, offset, value);
1786      return;
1787   }
1788   
1789   /* Sanity check. Higher slots are always empty. */
1790   if (slot >= NUMBER_OF_CARTRIDGE_SLOTS)
1791      return;
1792
1793   /* Same as above (READ16). */
1794   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1795      slot=0;
1796
1797   cart = &cartslots->cartridge[slot];
1798
1799   if (!slot_is_empty(device, slot))
1800   {
1801      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cart->pcb)->token();;
1802      if (pcbdef->cruread != NULL)
1803         (*pcbdef->cruread)(cart->pcb, offset, value);
1804   }
1805}
1806
1807/*
1808    Write cartridge mapper CRU interface (SuperSpace, Pagedcru)
1809*/
1810WRITE8_DEVICE_HANDLER( gromportc_w )
1811{
1812   ti99_multicart_state *cartslots = (ti99_multicart_state *) downcast<legacy_device_base *>(device)->token();
1813   cartridge_t *cart;
1814
1815   int slot = cartslots->active_slot;
1816
1817   // Handle GRAM Kracker
1818   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1819   {
1820      ti99_cart_cru_gk_w(device, offset, data);
1821      return;
1822   }
1823   
1824   /* Sanity check. Higher slots are always empty. */
1825   if (slot >= NUMBER_OF_CARTRIDGE_SLOTS)
1826      return;
1827
1828   /* Same as above (READ16). */
1829   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1830      slot=0;
1831
1832   cart = &cartslots->cartridge[slot];
1833
1834   if (!slot_is_empty(device, slot))
1835   {
1836      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cart->pcb)->token();;
1837      if (pcbdef->cruwrite != NULL)
1838         (*pcbdef->cruwrite)(cart->pcb, offset, data);
1839   }
1840}
1841
1842/*****************************************************************************
1843   GramKracker support
1844   The 80 KiB of the GK are allocated as follows
1845   00000 - 01fff: GRAM 0
1846   02000 - 03fff: GRAM 1  (alternatively, the loader GROM appears here)
1847   04000 - 05fff: GRAM 2
1848   06000 - 0ffff: GRAM 3-7 (alternatively, the guest GROMs appear here)
1849   10000 - 11fff: RAM 1
1850   12000 - 13fff: RAM 2
1851   
1852   The GK emulates GROMs, but without a readable address counter. Thus it
1853   relies on the console GROMs being still in place (compare with the HSGPL).
1854   Also, the GK does not implement a GROM buffer.
1855******************************************************************************/
1856
1857/*
1858    Reads from the GRAM space of the GRAM Kracker.
1859*/
1860static void cartridge_gram_kracker_readg(running_device *cartsys, UINT8 *value)
1861{
1862   // gk_slot is the slot where the GK module is plugged in
1863   // gk_guest_slot is the slot where the cartridge is plugged in
1864
1865   cartridge_t *gromkrackerbox, *gkguestcart;
1866   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1867
1868   // Not null, since this is only called when there is really a GK module
1869   gromkrackerbox = &cartslots->cartridge[cartslots->gk_slot];
1870
1871   if ((gromkrackerbox->grom_address & 0xe000) == 0x0000)
1872   {
1873      // GRAM 0. Only return a value if switch 2 is in GRAM0 position.
1874      if (get_gk_switch(cartsys, 2)==GK_GRAM0)
1875         *value = (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address];
1876   }
1877   
1878   if ((gromkrackerbox->grom_address & 0xe000) == 0x2000)
1879   {
1880      // If the loader is turned on, return loader contents.
1881      if (get_gk_switch(cartsys, 5)==GK_LDON)
1882      {
1883         // The only ROM contained in the GK box is the loader
1884         *value = gromkrackerbox->grom_ptr[gromkrackerbox->grom_address & 0x1fff];
1885      }
1886      else
1887      {
1888         // Loader off
1889         // GRAM 1. Only return a value if switch 3 is in GRAM12 position.
1890         if (get_gk_switch(cartsys, 3)==GK_GRAM12)
1891            *value = (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address];
1892      }
1893   }
1894
1895   if ((gromkrackerbox->grom_address & 0xe000) == 0x4000)
1896   {
1897      // GRAM 2. Only return a value if switch 3 is in GRAM12 position.
1898      if (get_gk_switch(cartsys, 3)==GK_GRAM12)
1899         *value = (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address];
1900   }
1901
1902   if (((gromkrackerbox->grom_address & 0xe000) == 0x6000) ||
1903      ((gromkrackerbox->grom_address & 0x8000) == 0x8000))
1904   {
1905      // Cartridge space
1906      // When a cartridge is installed, it overrides the GK contents
1907      // but only if it has GROMs     
1908      int cartwithgrom = FALSE;
1909      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
1910
1911      // Send the request to all mounted GROMs
1912      if (gkguestcart->pcb!=NULL)
1913      {
1914         for (int i=0; i < 5; i++)
1915         {
1916            ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
1917            if (pcbdef->grom[i]!=NULL)
1918            {
1919               ti99grom_rz(pcbdef->grom[i], 0x9800, value);
1920               cartwithgrom = TRUE;
1921            }
1922         }
1923      }
1924      if (!cartwithgrom && get_gk_switch(cartsys, 1)==GK_NORMAL)
1925      {
1926         *value = (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address];         
1927      }
1928   }
1929
1930   // The GK GROM emulation does not wrap at 8K boundaries.
1931   gromkrackerbox->grom_address = (gromkrackerbox->grom_address+1) & 0xffff;
1932
1933   /* Reset the write address flipflop. */
1934   gromkrackerbox->waddr_LSB = FALSE;
1935}
1936
1937/*
1938    Writes to the GRAM space of the GRAM Kracker.
1939*/
1940static void cartridge_gram_kracker_writeg(running_device *cartsys, int offset, UINT8 data)
1941{
1942   // gk_slot is the slot where the GK module is plugged in
1943   // gk_guest_slot is the slot where the cartridge is plugged in
1944   cartridge_t *gromkrackerbox;
1945   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1946
1947   // This is only called when there is really a GK module
1948   gromkrackerbox = &cartslots->cartridge[cartslots->gk_slot];
1949
1950   if ((offset & 0x0002)==0x0002)
1951   {
1952      // Set address     
1953      if (gromkrackerbox->waddr_LSB)
1954      {
1955         /* Accept low byte (2nd write) */
1956         gromkrackerbox->grom_address = (gromkrackerbox->grom_address & 0xff00) | data;
1957         gromkrackerbox->waddr_LSB = FALSE;
1958      }
1959      else
1960      {
1961         /* Accept high byte (1st write) */
1962         gromkrackerbox->grom_address = ((data<<8) & 0xff00) | (gromkrackerbox->grom_address & 0x00ff);
1963         gromkrackerbox->waddr_LSB = TRUE;
1964      }
1965   }
1966   else
1967   {
1968      if (get_gk_switch(cartsys, 4) != GK_WP)
1969      {
1970         // Write protection off
1971         if (   (((gromkrackerbox->grom_address & 0xe000)==0x0000) && get_gk_switch(cartsys, 2)==GK_GRAM0)
1972            || (((gromkrackerbox->grom_address & 0xe000)==0x2000) && get_gk_switch(cartsys, 3)==GK_GRAM12 && (get_gk_switch(cartsys, 5)==GK_LDOFF))
1973            || (((gromkrackerbox->grom_address & 0xe000)==0x4000) && get_gk_switch(cartsys, 3)==GK_GRAM12)
1974            || (((gromkrackerbox->grom_address & 0xe000)==0x6000) && get_gk_switch(cartsys, 1)==GK_NORMAL && (cartslots->gk_guest_slot==-1))
1975            || (((gromkrackerbox->grom_address & 0x8000)==0x8000) && get_gk_switch(cartsys, 1)==GK_NORMAL && (cartslots->gk_guest_slot==-1)))
1976         {
1977            (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address] = data;
1978         }
1979      }
1980      // The GK GROM emulation does not wrap at 8K boundaries.
1981      gromkrackerbox->grom_address = (gromkrackerbox->grom_address+1) & 0xffff;
1982     
1983      /* Reset the write address flipflop. */
1984      gromkrackerbox->waddr_LSB = FALSE;
1985   }
1986}
1987
1988/*
1989    Reads from the RAM space of the GRAM Kracker.
1990*/
1991static READ8Z_DEVICE_HANDLER( ti99_cart_gk_rz )
1992{
1993   // gk_slot is the slot where the GK module is plugged in
1994   // gk_guest_slot is the slot where the cartridge is plugged in
1995   cartridge_t *gromkrackerbox, *gkguestcart;
1996   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1997
1998   gromkrackerbox = &cartslots->cartridge[cartslots->gk_slot];
1999
2000   if (cartslots->gk_guest_slot != -1)
2001   {
2002      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
2003      // Legacy mode is not supported with the GK
2004      if (in_legacy_mode(device))
2005      {
2006         return;
2007      }
2008      //      printf("accessing cartridge in slot %d\n", slot);
2009      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
2010      //      printf("address=%lx, offset=%lx\n", pcbdef, offset);
2011      (*pcbdef->read)(gkguestcart->pcb, offset, value);
2012      return;
2013   }
2014   else
2015   {
2016      if (get_gk_switch(device, 1)==GK_OFF) return;
2017      if (get_gk_switch(device, 4)==GK_BANK1)
2018      {
2019         *value = (gromkrackerbox->ram_ptr)[offset+0x10000];
2020      }
2021      else
2022      {
2023         if (get_gk_switch(device, 4)==GK_BANK2)
2024         {
2025            *value = (gromkrackerbox->ram_ptr)[offset+0x12000];
2026         }
2027         else
2028         {
2029            // Write protection on; auto-bank
2030            if (gromkrackerbox->ram_page==0)
2031            {
2032               *value = (gromkrackerbox->ram_ptr)[offset+0x10000];
2033            }
2034            else
2035            {
2036               *value = (gromkrackerbox->ram_ptr)[offset+0x12000];
2037            }
2038         }
2039      }
2040   }
2041}
2042
2043/*
2044    Writes to the RAM space of the GRAM Kracker.
2045*/
2046static WRITE8_DEVICE_HANDLER( ti99_cart_gk_w )
2047{
2048   // gk_slot is the slot where the GK module is plugged in
2049   // gk_guest_slot is the slot where the cartridge is plugged in
2050   cartridge_t *gromkrackerbox, *gkguestcart;
2051   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
2052
2053   gromkrackerbox = &cartslots->cartridge[cartslots->gk_slot];
2054
2055   if (cartslots->gk_guest_slot != -1)
2056   {
2057      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
2058      // Legacy mode is not supported with the GK
2059      if (in_legacy_mode(device))
2060      {
2061         return;
2062      }
2063
2064      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
2065         (*pcbdef->write)(gkguestcart->pcb, offset, data);
2066   }
2067   else
2068   {
2069      if (get_gk_switch(device, 1)==GK_OFF)
2070         return;
2071
2072      if (get_gk_switch(device, 4)==GK_BANK1)
2073      {
2074         (gromkrackerbox->ram_ptr)[offset + 0x10000] = data;
2075      }
2076      else
2077      {
2078         if (get_gk_switch(device, 4)==GK_BANK2)
2079         {
2080            (gromkrackerbox->ram_ptr)[offset + 0x12000] = data;
2081         }
2082         else
2083         {
2084            // Write protection on
2085            // This is handled like in Extended Basic
2086            gromkrackerbox->ram_page = (offset & 2)>>1;
2087         }
2088      }
2089   }
2090}
2091
2092/*
2093    Read cartridge mapper CRU interface (Guest in GRAM Kracker)
2094*/
2095static READ8Z_DEVICE_HANDLER( ti99_cart_cru_gk_rz )
2096{
2097   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
2098   cartridge_t *gkguestcart;
2099
2100   if (cartslots->gk_guest_slot != -1)
2101   {
2102      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
2103      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
2104      if (pcbdef->cruread != NULL)
2105         (*pcbdef->cruread)(gkguestcart->pcb, offset, value);
2106   }
2107}
2108
2109/*
2110    Write cartridge mapper CRU interface (Guest in GRAM Kracker)
2111*/
2112static WRITE8_DEVICE_HANDLER( ti99_cart_cru_gk_w )
2113{
2114   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
2115   cartridge_t *gkguestcart;
2116
2117   if (cartslots->gk_guest_slot != -1)
2118   {
2119      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
2120      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
2121      if (pcbdef->cruwrite != NULL)
2122         (*pcbdef->cruwrite)(gkguestcart->pcb, offset, data);
2123   }
2124}
2125
2126/*****************************************************************************/
2127#define TI99_CARTRIDGE_SLOT(p)  MDRV_CARTSLOT_ADD(p) \
2128   MDRV_CARTSLOT_EXTENSION_LIST("rpk,bin") \
2129   MDRV_CARTSLOT_PCBTYPE(0, "none", TI99_CARTRIDGE_PCB_NONE) \
2130   MDRV_CARTSLOT_PCBTYPE(1, "standard", TI99_CARTRIDGE_PCB_STD) \
2131   MDRV_CARTSLOT_PCBTYPE(2, "paged", TI99_CARTRIDGE_PCB_PAGED) \
2132   MDRV_CARTSLOT_PCBTYPE(3, "minimem", TI99_CARTRIDGE_PCB_MINIMEM) \
2133   MDRV_CARTSLOT_PCBTYPE(4, "super", TI99_CARTRIDGE_PCB_SUPER) \
2134   MDRV_CARTSLOT_PCBTYPE(5, "mbx", TI99_CARTRIDGE_PCB_MBX) \
2135   MDRV_CARTSLOT_PCBTYPE(6, "paged379i", TI99_CARTRIDGE_PCB_PAGED379I) \
2136   MDRV_CARTSLOT_PCBTYPE(7, "pagedcru", TI99_CARTRIDGE_PCB_PAGEDCRU) \
2137   MDRV_CARTSLOT_PCBTYPE(8, "gramkracker", TI99_CARTRIDGE_PCB_GRAMKRACKER) \
2138   MDRV_CARTSLOT_START(ti99_cartridge) \
2139   MDRV_CARTSLOT_LOAD(ti99_cartridge) \
2140   MDRV_CARTSLOT_UNLOAD(ti99_cartridge)
2141
2142static MACHINE_CONFIG_FRAGMENT(ti99_multicart)
2143   TI99_CARTRIDGE_SLOT("cartridge1")
2144   TI99_CARTRIDGE_SLOT("cartridge2")
2145   TI99_CARTRIDGE_SLOT("cartridge3")
2146   TI99_CARTRIDGE_SLOT("cartridge4")
2147MACHINE_CONFIG_END
2148
2149static const char DEVTEMPLATE_SOURCE[] = __FILE__;
2150
2151#define DEVTEMPLATE_ID(p,s)             p##ti99_multicart##s
2152#define DEVTEMPLATE_FEATURES            DT_HAS_START | DT_HAS_STOP | DT_HAS_RESET | DT_HAS_INLINE_CONFIG | DT_HAS_MACHINE_CONFIG
2153#define DEVTEMPLATE_NAME                "TI99 Multi-Cartridge Extender"
2154#define DEVTEMPLATE_FAMILY              "Multi-cartridge system"
2155#include "devtempl.h"
2156
2157DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_MULTICART, ti99_multicart);
1/**********************************************************************
2 
3    gromport.c
4 
5*********************************************************************/
6 
7#include "emu.h"
8#include "gromport.h"
9#include "devices/cartslot.h"
10#include "devices/multcart.h"
11#include "grom.h"
12 
13typedef UINT8   (*read8z_device_func)  (ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, UINT8 *value);
14 
15/* We set the number of slots to 8, although we may have up to 16. From a
16   logical point of view we could have 256, but the operating system only checks
17   the first 16 banks. */
18#define NUMBER_OF_CARTRIDGE_SLOTS 8
19 
20typedef int assmfct(running_device *);
21 
22DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_NONE, ti99_cartridge_pcb_none);
23DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_STD, ti99_cartridge_pcb_std);
24DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGED, ti99_cartridge_pcb_paged);
25DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_MINIMEM, ti99_cartridge_pcb_minimem);
26DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_SUPER, ti99_cartridge_pcb_super);
27DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_MBX, ti99_cartridge_pcb_mbx);
28DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGED379I, ti99_cartridge_pcb_paged379i);
29DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGEDCRU, ti99_cartridge_pcb_pagedcru);
30DECLARE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_GRAMKRACKER, ti99_cartridge_pcb_gramkracker);
31 
32DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_NONE, ti99_cartridge_pcb_none);
33DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_STD, ti99_cartridge_pcb_std);
34DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGED, ti99_cartridge_pcb_paged);
35DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_MINIMEM, ti99_cartridge_pcb_minimem);
36DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_SUPER, ti99_cartridge_pcb_super);
37DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_MBX, ti99_cartridge_pcb_mbx);
38DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGED379I, ti99_cartridge_pcb_paged379i);
39DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_PAGEDCRU, ti99_cartridge_pcb_pagedcru);
40DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_CARTRIDGE_PCB_GRAMKRACKER, ti99_cartridge_pcb_gramkracker);
41 
42/* Generic TI99 cartridge structure. */
43struct _cartridge_t
44{
45   // PCB device associated to this cartridge. If NULL, the slot is empty.
46   running_device *pcb;
47 
48   // ROM page.
49   int rom_page;
50 
51   // RAM page.
52   int ram_page;
53 
54   // GROM buffer size.
55   int grom_size;
56   
57   // ROM buffer size. All banks have equal sizes.
58   int rom_size;
59   
60   // RAM buffer size. All banks have equal sizes.
61   int ram_size;
62 
63   // GROM buffer. 
64   UINT8 *grom_ptr;
65 
66   // ROM buffer. 
67   UINT8 *rom_ptr;
68 
69   // ROM buffer for the second bank of paged cartridges.
70   UINT8 *rom2_ptr;
71 
72   // RAM buffer. The persistence service is done by the cartridge system.
73   // The RAM space is a consecutive space; all banks are in one buffer.
74   UINT8 *ram_ptr;
75   
76   /* GK support. */
77   UINT16   grom_address;   
78   int      waddr_LSB;
79};
80typedef struct _cartridge_t cartridge_t;
81 
82enum
83{
84   TI99CARTINFO_FCT_6000_R = DEVINFO_FCT_DEVICE_SPECIFIC,
85   TI99CARTINFO_FCT_6000_W,
86   TI99CARTINFO_FCT_CRU_R,
87   TI99CARTINFO_FCT_CRU_W,
88   TI99CART_FCT_ASSM,
89   TI99CART_FCT_DISASSM
90};
91 
92typedef struct _ti99_multicart_state
93{
94   // Reserves space for all cartridges. This is also used in the legacy
95   // cartridge system, but only for slot 0.
96   cartridge_t cartridge[NUMBER_OF_CARTRIDGE_SLOTS];
97 
98   // Determines which slot is currently active. This value is changed when
99   // there are accesses to other GROM base addresses.
100   int    active_slot;
101 
102   // Used in order to enforce a special slot. This value is retrieved
103   // from the dipswitch setting. A value of -1 means automatic, that is,
104   // the grom base switch is used. Values 0 .. max refer to the
105   // respective slot.
106   int    fixed_slot;
107 
108   // Holds the highest index of a cartridge being plugged in plus one.
109   // If we only have one cartridge inserted, we don't want to get a
110   // selection option, so we just mirror the memory contents.
111   int    next_free_slot;
112   
113   /* GK support. */
114   int      gk_slot;
115   int      gk_guest_slot;
116   
117   /* Legacy support. */
118   // Counts the number of slots which currently contain legacy format
119   // cartridge images.
120   int legacy_slots;
121 
122   // Counts the number of slots which currently contain new format
123   // cartridge images.
124   int multi_slots;
125   
126   /* Used to cache the switch settings. */
127   UINT8 gk_switch[8];
128 
129   /* Ready line */
130   devcb_resolved_write_line ready;
131   
132} ti99_multicart_state;
133 
134#define AUTO -1
135 
136/* Access to the pcb. Contained in the token of the pcb instance. */
137struct _ti99_pcb_t
138{
139   /* Read function for this cartridge. */
140   read8z_device_func read;
141 
142   /* Write function for this cartridge. */
143   write8_device_func write;
144 
145   /* Read function for this cartridge, CRU. */
146   read8z_device_func cruread;
147 
148   /* Write function for this cartridge, CRU. */
149   write8_device_func cruwrite;
150 
151   /* Link up to the cartridge structure which contains this pcb. */
152   cartridge_t *cartridge;
153 
154   /* Function to assemble this cartridge. */
155   assmfct   *assemble;
156 
157   /* Function to disassemble this cartridge. */
158   assmfct   *disassemble;
159   
160   /* Points to the (max 5) GROM devices. */
161   running_device *grom[5];
162};
163typedef struct _ti99_pcb_t ti99_pcb_t;
164 
165INLINE ti99_multicart_state *get_safe_token(running_device *device)
166{
167   assert(device != NULL);
168   return (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
169}
170 
171INLINE const ti99_multicart_config *get_config(running_device *device)
172{
173   assert(device != NULL);
174   assert(device->type() == TI99_MULTICART);
175   return (const ti99_multicart_config *) downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
176}
177 
178INLINE ti99_pcb_t *get_safe_pcb_token(running_device *device)
179{
180   assert(device != NULL);
181   return (ti99_pcb_t *)downcast<legacy_device_base *>(device)->token();
182}
183 
184static WRITE_LINE_DEVICE_HANDLER( cart_grom_ready )
185{
186   running_device *cartdev = device->owner()->owner();
187   ti99_multicart_state *cartslots = get_safe_token(cartdev);
188   devcb_call_write_line( &cartslots->ready, state );
189}
190 
191/*
192   The console writes the values in this array to cache them.
193*/
194void set_gk_switches(running_device *cartsys, int number, int value)
195{
196   ti99_multicart_state *cartslots = get_safe_token(cartsys);
197   cartslots->gk_switch[number] = value;
198}
199 
200static int get_gk_switch(running_device *cartsys, int number)
201{
202   ti99_multicart_state *cartslots = get_safe_token(cartsys);
203   return cartslots->gk_switch[number];
204}
205 
206static int in_legacy_mode(running_device *device)
207{
208   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
209   return ((cartslots->legacy_slots>0) && (cartslots->multi_slots==0));
210}
211 
212/*
213    Activates a slot in the multi-cartridge extender.
214*/
215static void cartridge_slot_set(running_device *cartsys, UINT8 slotnumber)
216{
217   ti99_multicart_state *cartslots = get_safe_token(cartsys);
218//  if (cartslots->active_slot != slotnumber) printf("Setting cartslot to %d\n", slotnumber);
219   if (cartslots->fixed_slot==AUTO)
220      cartslots->active_slot = slotnumber;
221   else
222      cartslots->active_slot = cartslots->fixed_slot;
223}
224 
225static int slot_is_empty(running_device *cartsys, int slotnumber)
226{
227   cartridge_t *cart;
228   ti99_multicart_state *cartslots = get_safe_token(cartsys);
229 
230   cart = &cartslots->cartridge[slotnumber];
231 
232   if ((cart->rom_size==0) && (cart->ram_size==0) && (cart->grom_size==0))
233      return TRUE;
234   return FALSE;
235}
236 
237static void clear_slot(running_device *cartsys, int slotnumber)
238{
239   cartridge_t *cart;
240   ti99_multicart_state *cartslots = get_safe_token(cartsys);
241 
242   cart = &cartslots->cartridge[slotnumber];
243 
244   cart->rom_size = cart->ram_size = cart->grom_size = 0;
245   cart->rom_ptr = NULL;
246   cart->rom2_ptr = NULL;
247   cart->ram_ptr = NULL;
248}
249 
250/*
251    Find the index of the cartridge name. We assume the format
252    <name><number>, i.e. the number is the longest string from the right
253    which can be interpreted as a number.
254*/
255static int get_index_from_tagname(running_device *image)
256{
257   const char *tag = image->tag();
258   int maxlen = strlen(tag);
259   int i;
260   for (i=maxlen-1; i >=0; i--)
261      if (tag[i] < 48 || tag[i] > 57) break;
262 
263   return atoi(tag+i+1);
264}
265 
266/*
267    Common routine to assemble cartridges from resources.
268*/
269static cartridge_t *assemble_common(running_device *cartslot)
270{
271   /* Pointer to the cartridge structure. */
272   cartridge_t *cartridge;
273   running_device *cartsys = cartslot->owner();
274   ti99_multicart_state *cartslots = get_safe_token(cartsys);
275   running_device *pcb = cartslot->subdevice("pcb");
276   ti99_pcb_t *pcb_def;
277   
278   void *socketcont;
279   int reslength;
280//   int i;
281 
282   int slotnumber = get_index_from_tagname(cartslot)-1;
283   assert(slotnumber>=0 && slotnumber<NUMBER_OF_CARTRIDGE_SLOTS);
284 
285   /* There is a cartridge in this slot, check the maximum slot number. */
286   if (cartslots->next_free_slot <= slotnumber)
287   {
288      cartslots->next_free_slot = slotnumber+1;
289   }
290   cartridge = &cartslots->cartridge[slotnumber];
291 
292   // Get the socket which is retrieved by the multicart instance in
293   // the state of the cartslot instance.
294   socketcont = cartslot_get_socket(cartslot, "grom_socket");
295   reslength = cartslot_get_resource_length(cartslot, "grom_socket");
296   if (socketcont != NULL)
297   {
298      cartridge->grom_ptr = (UINT8 *)socketcont;
299//      printf("grom_socket = %lx\n", cartridge->grom_ptr);
300      cartridge->grom_size = reslength;
301   }
302 
303   socketcont = cartslot_get_socket(cartslot, "rom_socket");
304   reslength = cartslot_get_resource_length(cartslot, "rom_socket");
305   if (socketcont != NULL)
306   {
307      cartridge->rom_ptr = (UINT8 *)socketcont;
308      cartridge->rom_size = reslength;
309//      printf("set rom ptr = %lx, romlength = %04x, data = %02x %02x\n", cartridge->rom_ptr, cartridge->rom_size, cartridge->rom_ptr[0], cartridge->rom_ptr[1]);
310   }
311 
312   socketcont = cartslot_get_socket(cartslot, "rom2_socket");
313//  reslength = cartslot_get_resource_length(cartslot, "rom2_socket");  /* cannot differ from rom_socket */
314   if (socketcont != NULL)
315   {
316      cartridge->rom2_ptr = (UINT8 *)socketcont;
317   }
318 
319   socketcont = cartslot_get_socket(cartslot, "ram_socket");
320   reslength = cartslot_get_resource_length(cartslot, "ram_socket");
321   if (socketcont != NULL)
322   {
323      cartridge->ram_ptr = (UINT8 *)socketcont;
324      cartridge->ram_size = reslength;
325   }
326 
327   // Register the GROMs
328   pcb_def = (ti99_pcb_t *)downcast<legacy_device_base *>(pcb)->token();
329   for (int i=0; i < 5; i++) pcb_def->grom[i]= NULL;
330   if (cartridge->grom_size > 0)      pcb_def->grom[0] = pcb->subdevice("grom_3");
331   if (cartridge->grom_size > 0x2000) pcb_def->grom[1] = pcb->subdevice("grom_4");
332   if (cartridge->grom_size > 0x4000) pcb_def->grom[2] = pcb->subdevice("grom_5");
333   if (cartridge->grom_size > 0x6000) pcb_def->grom[3] = pcb->subdevice("grom_6");
334   if (cartridge->grom_size > 0x8000) pcb_def->grom[4] = pcb->subdevice("grom_7");
335   
336   return cartridge;
337}
338 
339static void set_pointers(running_device *pcb, int index)
340{
341   running_device *cartsys = pcb->owner()->owner();
342   ti99_multicart_state *cartslots = get_safe_token(cartsys);
343   ti99_pcb_t *pcb_def = (ti99_pcb_t *)downcast<legacy_device_base *>(pcb)->token();
344 
345   pcb_def->read = (read8z_device_func)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CARTINFO_FCT_6000_R);
346   pcb_def->write = (write8_device_func)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CARTINFO_FCT_6000_W);
347   pcb_def->cruread = (read8z_device_func)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CARTINFO_FCT_CRU_R);
348   pcb_def->cruwrite = (write8_device_func)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CARTINFO_FCT_CRU_W);
349 
350    pcb_def->assemble = (assmfct *)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CART_FCT_ASSM);
351    pcb_def->disassemble = (assmfct *)downcast<const legacy_cart_slot_device_config_base *>(&pcb->baseconfig())->get_config_fct(TI99CART_FCT_DISASSM);
352 
353   pcb_def->cartridge = &cartslots->cartridge[index];
354   pcb_def->cartridge->pcb = pcb;
355}
356 
357/*****************************************************************************
358  Cartridge type: None
359    This PCB device is just a pseudo device; the legacy mode is handled
360    by dedicated functions.
361******************************************************************************/
362static DEVICE_START(ti99_pcb_none)
363{
364   /* device is ti99_cartslot:cartridge:pcb */
365   set_pointers(device, get_index_from_tagname(device->owner())-1);
366}
367 
368/*****************************************************************************
369  Cartridge type: Standard
370    Most cartridges are built in this type. Every cartridge may contain
371    GROM between 0 and 40 KiB, and ROM with 8 KiB length, no banking.
372******************************************************************************/
373 
374static DEVICE_START(ti99_pcb_std)
375{
376   /* device is ti99_cartslot:cartridge:pcb */
377   set_pointers(device, get_index_from_tagname(device->owner())-1);
378}
379 
380/*
381    Read handler for the CPU address space of the cartridge
382    Images for this area are found in the rom_sockets.
383*/
384static READ8Z_DEVICE_HANDLER( read_cart_std )
385{
386   /* device is pcb, owner is cartslot (cartridge is only a part of the state of cartslot) */
387   ti99_pcb_t *pcb = get_safe_pcb_token(device);
388   cartridge_t *cartridge = pcb->cartridge;
389   if (cartridge->rom_ptr!=NULL)
390   {
391      // For TI-99/8 we should plan for 16K cartridges. However, none was produced. Well, just ignore this thought,
392      *value = (cartridge->rom_ptr)[offset & 0x1fff];   
393//      printf("read cartridge rom space (length %04x) %04x = %02x\n", cartridge->rom_size, offset, *value);
394   }
395}
396 
397static WRITE8_DEVICE_HANDLER( write_cart_std )
398{
399   logerror("Write access to cartridge ROM at address %04x ignored\n", offset);
400}
401 
402/*
403    The standard cartridge assemble routine. We just call the common
404    function here.
405*/
406static int assemble_std(running_device *image)
407{
408   assemble_common(image);
409   return IMAGE_INIT_PASS;
410}
411 
412/*
413    Removes pointers and restores the state before plugging in the
414    cartridge.
415    The pointer to the location after the last cartridge is adjusted.
416    As it seems, we can use the same function for the disassembling of all
417    cartridge types.
418*/
419static int disassemble_std(running_device *image)
420{
421   int slotnumber;
422   int i;
423//   cartridge_t *cart;
424   running_device *cartsys = image->owner();
425   ti99_multicart_state *cartslots = get_safe_token(cartsys);
426 
427   slotnumber = get_index_from_tagname(image)-1;
428 
429   /* Search the highest remaining cartridge. */
430   cartslots->next_free_slot = 0;
431   for (i=NUMBER_OF_CARTRIDGE_SLOTS-1; i >= 0; i--)
432   {
433      if (i != slotnumber)
434      {
435         if (!slot_is_empty(cartsys, i))
436         {
437            cartslots->next_free_slot = i+1;
438            break;
439         }
440      }
441   }
442 
443   clear_slot(cartsys, slotnumber);
444 
445   return IMAGE_INIT_PASS;
446}
447 
448/*****************************************************************************
449  Cartridge type: Paged (Extended Basic)
450    This cartridge consists of GROM memory and 2 pages of standard ROM.
451    The page is set by writing any value to a location in
452    the address area, where an even word offset sets the page to 0 and an
453    odd word offset sets the page to 1 (e.g. 6000 = bank 0, and
454    6002 = bank 1).
455******************************************************************************/
456 
457static DEVICE_START(ti99_pcb_paged)
458{
459   /* device is ti99_cartslot:cartridge:pcb */
460   set_pointers(device, get_index_from_tagname(device->owner())-1);
461}
462 
463/*
464    Read handler for the CPU address space of the cartridge
465    Images for this area are found in the rom_sockets.
466*/
467static READ8Z_DEVICE_HANDLER( read_cart_paged )
468{
469   /* device is pcb, owner is cartslot */
470   ti99_pcb_t *pcb = get_safe_pcb_token(device);
471   cartridge_t *cartridge = pcb->cartridge;
472   UINT8 *rombank;
473 
474   if (cartridge->rom_page==0)
475      rombank = (UINT8*)cartridge->rom_ptr;
476   else
477      rombank = (UINT8*)cartridge->rom2_ptr;
478 
479   if (rombank==NULL)
480   {
481      /* TODO: Check for consistency with the GROM memory handling. */
482      *value = 0;
483   }
484   else
485   {
486      *value = rombank[offset & 0x1fff];
487   }
488}
489 
490/*
491    Handle paging. Extended Basic switches between ROM banks by
492    using the value of the LSB of the address where any value
493    is written to.
494*/
495static WRITE8_DEVICE_HANDLER( write_cart_paged )
496{
497   ti99_pcb_t *pcb = get_safe_pcb_token(device);
498   cartridge_t *cartridge = pcb->cartridge;
499   cartridge->rom_page = (offset >> 1) & 1;
500}
501 
502/*
503    We require paged modules to have at least those two rom banks.
504*/
505static int assemble_paged(running_device *image)
506{
507   cartridge_t *cart;
508 
509   cart = assemble_common(image);
510   if (cart->rom_ptr==NULL)
511   {
512      logerror("Missing ROM for paged cartridge");
513      return IMAGE_INIT_FAIL;
514   }
515   if (cart->rom2_ptr==NULL)
516   {
517      logerror("Missing second ROM for paged cartridge");
518      return IMAGE_INIT_FAIL;
519   }
520 
521   return IMAGE_INIT_PASS;
522}
523 
524/*****************************************************************************
525  Cartridge type: Mini Memory
526    GROM: 6 KiB (occupies G>6000 to G>7800)
527    ROM: 4 KiB (romfile is actually 8 K long, second half with zeros, 0x6000-0x6fff)
528    persistent RAM: 4 KiB (0x7000-0x7fff)
529******************************************************************************/
530 
531static DEVICE_START(ti99_pcb_minimem)
532{
533   set_pointers(device, get_index_from_tagname(device->owner())-1);
534}
535 
536static READ8Z_DEVICE_HANDLER( read_cart_minimem )
537{
538   /* device is pcb, owner is cartslot */
539   ti99_pcb_t *pcb = get_safe_pcb_token(device);
540   cartridge_t *cartridge = pcb->cartridge;
541 
542   if ((offset & 0xf000)==0x6000)
543   {
544      *value = (cartridge->rom_ptr==NULL)? 0 : (cartridge->rom_ptr)[offset & 0x0fff];
545   }
546   else
547   {
548      *value = (cartridge->ram_ptr==NULL)? 0 : (cartridge->ram_ptr)[offset & 0x0fff];
549   }
550}
551 
552/*
553    Mini Memory cartridge write operation. RAM is located at 0x7000.
554*/
555static WRITE8_DEVICE_HANDLER( write_cart_minimem )
556{
557   ti99_pcb_t *pcb = get_safe_pcb_token(device);
558   cartridge_t *cartridge = pcb->cartridge;
559 
560   if (offset < 0x7000)
561   {
562      logerror("Write access to cartridge ROM at address %04x ignored", offset);
563   }
564   else
565   {
566      if (cartridge->ram_ptr==NULL)
567      {
568         logerror("No cartridge RAM at address %04x", offset);
569         /* TODO: Check for consistency with the GROM memory handling. */
570      }
571      else
572      {
573         (cartridge->ram_ptr)[offset-0x7000] = data;
574      }
575   }
576}
577 
578static int assemble_minimem(running_device *image)
579{
580   cartridge_t *cart;
581 
582   cart = assemble_common(image);
583   if (cart->grom_size==0)
584   {
585      logerror("Missing GROM for Mini Memory");
586      // should not fail here because there may be variations of
587      // cartridges which do not use all parts
588//      return IMAGE_INIT_FAIL;
589   }
590   if (cart->rom_size==0)
591   {
592      logerror("Missing ROM for Mini Memory");
593//      return IMAGE_INIT_FAIL;
594   }
595   if (cart->ram_size==0)
596   {
597      logerror("Missing RAM for Mini Memory");
598//      return IMAGE_INIT_FAIL;
599   }
600 
601   return IMAGE_INIT_PASS;
602}
603 
604/*****************************************************************************
605  Cartridge type: SuperSpace II
606    SuperSpace cartridge type. SuperSpace is intended as a user-definable
607    blank cartridge containing buffered RAM
608    It has an Editor/Assembler GROM which helps the user to load
609    the user program into the cartridge. If the user program has a suitable
610    header, the console recognizes the cartridge as runnable, and
611    assigns a number in the selection screen.
612    Switching the RAM banks in this cartridge is achieved by setting
613    CRU bits (the system serial interface).
614 
615    GROM: Editor/Assembler GROM
616    ROM: none
617    persistent RAM: 32 KiB (0x6000-0x7fff, 4 banks)
618    Switching the bank is done via CRU write
619******************************************************************************/
620 
621static DEVICE_START(ti99_pcb_super)
622{
623   set_pointers(device, get_index_from_tagname(device->owner())-1);
624}
625 
626/*
627    The CRU read handler. The CRU is a serial interface in the console.
628    Using the CRU we can switch the banks in the SuperSpace cartridge.
629*/
630static READ8Z_DEVICE_HANDLER( read_cart_cru )
631{
632   ti99_pcb_t *pcb = get_safe_pcb_token(device);
633   cartridge_t *cartridge = pcb->cartridge;
634   // offset is the bit number. The CRU base address is already divided  by 2.
635 
636   // ram_page contains the bank number. We have a maximum of
637   // 4 banks; the Super Space II manual says:
638   //
639   // Banks are selected by writing a bit pattern to CRU address >0800:
640   //
641   // Bank #   Value
642   // 0        >02  = 0000 0010
643   // 1        >08  = 0000 1000
644   // 2        >20  = 0010 0000
645   // 3        >80  = 1000 0000
646   //
647   // With the bank number (0, 1, 2, or 3) in R0:
648   //
649   // BNKSW   LI    R12,>0800   Set CRU address
650   //         LI    R1,2        Load Shift Bit
651   //         SLA   R0,1        Align Bank Number
652   //         JEQ   BNKS1       Skip shift if Bank 0
653   //         SLA   R1,0        Align Shift Bit
654   // BNKS1   LDCR  R1,0        Switch Banks
655   //         SRL   R0,1        Restore Bank Number (optional)
656   //         RT
657   printf("Superspace: CRU accessed at %04x\n", offset);
658   if ((offset & 1) == 0 || offset > 7)
659      *value = 0;
660 
661   // CRU addresses are only 1 bit wide. Bytes are transferred from LSB
662   // to MSB. That is, 8 bit are eight consecutive addresses. */
663   *value = (cartridge->ram_page == (offset-1)/2);
664}
665 
666static WRITE8_DEVICE_HANDLER( write_cart_cru )
667{
668   ti99_pcb_t *pcb = get_safe_pcb_token(device);
669   cartridge_t *cartridge = pcb->cartridge;
670   // data is bit
671   // offset is address
672   printf("Superspace: CRU accessed at %04x\n", offset);
673   if (offset < 8)
674   {
675      if (data != 0)
676         cartridge->ram_page = (offset-1)/2;
677   }
678}
679 
680/*
681    SuperSpace RAM read operation. RAM is located at 0x6000 to 0x7fff
682    as 4 banks of 8 KiB each
683*/
684static READ8Z_DEVICE_HANDLER( read_cart_super )
685{
686   /* device is pcb, owner is cartslot */
687   ti99_pcb_t *pcb = get_safe_pcb_token(device);
688   cartridge_t *cartridge = pcb->cartridge;
689   offs_t boffset;
690 
691   if (cartridge->ram_ptr==NULL)
692   {
693      *value = 0;
694   }
695   else
696   {
697      boffset = cartridge->ram_page * 0x2000 + (offset & 0x1fff);
698      *value = (cartridge->ram_ptr)[boffset];
699   }
700}
701 
702/*
703    SuperSpace RAM write operation. RAM is located at 0x6000 to 0x7fff
704    as 4 banks of 8 KiB each
705*/
706static WRITE8_DEVICE_HANDLER( write_cart_super )
707{
708   ti99_pcb_t *pcb = get_safe_pcb_token(device);
709   cartridge_t *cartridge = pcb->cartridge;
710   offs_t boffset;
711 
712   if (cartridge->ram_ptr==NULL)
713   {
714      logerror("No cartridge RAM at address %04x", offset);
715   }
716   else
717   {
718      boffset = cartridge->ram_page * 0x2000 + (offset & 0x1fff);
719      (cartridge->ram_ptr)[boffset] = data;
720   }
721}
722 
723static int assemble_super(running_device *image)
724{
725   cartridge_t *cart;
726 
727   cart = assemble_common(image);
728   if (cart->ram_size==0)
729   {
730      logerror("Missing RAM for SuperSpace");
731      return IMAGE_INIT_FAIL;
732   }
733   return IMAGE_INIT_PASS;
734}
735 
736/*****************************************************************************
737  Cartridge type: MBX
738    GROM: up to 40 KiB
739    ROM: up to 16 KiB (in up to 2 banks of 8KiB each)
740    RAM: 1022 B (0x6c00-0x6ffd, overrides ROM in that area)
741    ROM mapper: 6ffe
742 
743    Note that some MBX cartridges assume the presence of the MBX system
744    (additional console) and will not run without it. The MBX hardware is
745    not emulated yet.
746******************************************************************************/
747 
748static DEVICE_START(ti99_pcb_mbx)
749{
750   set_pointers(device, get_index_from_tagname(device->owner())-1);
751}
752 
753static READ8Z_DEVICE_HANDLER( read_cart_mbx )
754{
755   /* device is pcb, owner is cartslot */
756   ti99_pcb_t *pcb = get_safe_pcb_token(device);
757   cartridge_t *cartridge = pcb->cartridge;
758 
759   if ((offset & 0x1c00)==0x0c00)
760   {
761      // This is the RAM area which overrides any ROM. There is no
762      // known banking behavior for the RAM, so we must assume that
763      // there is only one bank.
764      if (cartridge->ram_ptr != NULL)
765         *value = (cartridge->ram_ptr)[offset & 0x03ff];
766   }
767   else
768   {
769      if (cartridge->rom_ptr != NULL)
770         *value = (cartridge->rom_ptr)[(offset & 0x1fff)+ cartridge->rom_page*0x2000];
771   }
772}
773 
774/*
775    MBX write operation.
776*/
777static WRITE8_DEVICE_HANDLER( write_cart_mbx )
778{
779   ti99_pcb_t *pcb = get_safe_pcb_token(device);
780   cartridge_t *cartridge = pcb->cartridge;
781 
782   if (offset == 0x6ffe)
783   {
784      cartridge->rom_page = data & 1;
785      return;
786   }
787 
788   if ((offset & 0x1c00)==0x0c00)
789   {
790      if (cartridge->ram_ptr == NULL)   return;
791      cartridge->ram_ptr[offset - 0x6c00] = data;
792   }
793}
794 
795 
796static int assemble_mbx(running_device *image)
797{
798   assemble_common(image);
799   return IMAGE_INIT_PASS;
800}
801 
802/*****************************************************************************
803  Cartridge type: paged379i
804    This cartridge consists of one 16 KiB, 32 KiB, 64 KiB, or 128 KiB EEPROM
805    which is organised in 2, 4, 8, or 16 pages of 8 KiB each. The complete
806    memory contents must be stored in one dump file.
807    The pages are selected by writing a value to some memory locations. Due to
808    using the inverted outputs of the LS379 latch, setting the inputs of the
809    latch to all 0 selects the highest bank, while setting to all 1 selects the
810    lowest. There are some cartridges (16 KiB) which are using this scheme, and
811    there are new hardware developments mainly relying on this scheme.
812 
813    Writing to       selects page (16K/32K/64K/128K)
814    >6000            1 / 3 / 7 / 15
815    >6002            0 / 2 / 6 / 14
816    >6004            1 / 1 / 5 / 13
817    >6006            0 / 0 / 4 / 12
818    >6008            1 / 3 / 3 / 11
819    >600A            0 / 2 / 2 / 10
820    >600C            1 / 1 / 1 / 9
821    >600E            0 / 0 / 0 / 8
822    >6010            1 / 3 / 7 / 7
823    >6012            0 / 2 / 6 / 6
824    >6014            1 / 1 / 5 / 5
825    >6016            0 / 0 / 4 / 4
826    >6018            1 / 3 / 3 / 3
827    >601A            0 / 2 / 2 / 2
828    >601C            1 / 1 / 1 / 1
829    >601E            0 / 0 / 0 / 0
830 
831******************************************************************************/
832 
833static DEVICE_START(ti99_pcb_paged379i)
834{
835   /* device is ti99_cartslot:cartridge:pcb */
836   set_pointers(device, get_index_from_tagname(device->owner())-1);
837}
838 
839/*
840    Read handler for the CPU address space of the cartridge
841    Images for this area are found in the rom_sockets.
842*/
843static READ8Z_DEVICE_HANDLER( read_cart_paged379i )
844{
845   /* device is pcb, owner is cartslot */
846   ti99_pcb_t *pcb = get_safe_pcb_token(device);
847   cartridge_t *cartridge = pcb->cartridge;
848 
849   if (cartridge->rom_ptr!=NULL)
850   {
851      *value = (cartridge->rom_ptr)[cartridge->rom_page*0x2000 + (offset & 0x1fff)];
852   }
853}
854 
855/*
856   Determines which bank to set, depending on the size of the ROM. This is
857   some magic code that actually represents different PCB versions.
858*/
859static void set_paged379i_bank(cartridge_t *cartridge, int rompage)
860{
861   int mask = 0;
862   if (cartridge->rom_size > 16384)
863   {
864      if (cartridge->rom_size > 32768)
865      {
866         if (cartridge->rom_size > 65536)
867            mask = 15;
868         else
869            mask = 7;
870      }
871      else
872         mask = 3;
873   }
874   else
875      mask = 1;
876 
877   cartridge->rom_page = rompage & mask;
878}
879 
880/*
881    Handle paging. We use a LS379 latch for storing the page number. On this
882    PCB, the inverted output of the latch is used, so the order of pages
883    is reversed. (No problem as long as the memory dump is kept exactly
884    in the way it is stored in the EPROM.)
885    The latch can store a value of 4 bits. We adjust the number of
886    significant bits by the size of the memory dump (16K, 32K, 64K).
887*/
888static WRITE8_DEVICE_HANDLER( write_cart_paged379i )
889{
890   ti99_pcb_t *pcb = get_safe_pcb_token(device);
891   cartridge_t *cartridge = pcb->cartridge;
892 
893   // Bits: 011x xxxx xxxb bbbx
894   // x = don't care, bbbb = bank
895   set_paged379i_bank(cartridge, 15 - ((offset>>1) & 15));
896}
897 
898/*
899    Paged379i modules have one EPROM dump.
900*/
901static int assemble_paged379i(running_device *image)
902{
903   cartridge_t *cart;
904 
905   cart = assemble_common(image);
906   if (cart->rom_ptr==NULL)
907   {
908      logerror("Missing ROM for paged cartridge");
909      return IMAGE_INIT_FAIL;
910   }
911   set_paged379i_bank(cart, 15);
912   return IMAGE_INIT_PASS;
913}
914 
915/*****************************************************************************
916  Cartridge type: pagedcru
917    This cartridge consists of one 16 KiB, 32 KiB, or 64 KiB EEPROM which is
918    organised in 2, 4, or 8 pages of 8 KiB each. We assume there is only one
919    dump file of the respective size.
920    The pages are selected by writing a value to the CRU. This scheme is
921    similar to the one used for the SuperSpace cartridge, with the exception
922    that we are using ROM only, and we can have up to 8 pages.
923 
924    Bank     Value written to CRU>0800
925    0      >0002  = 0000 0000 0000 0010
926    1      >0008  = 0000 0000 0000 1000
927    2      >0020  = 0000 0000 0010 0000
928    3      >0080  = 0000 0000 1000 0000
929    4      >0200  = 0000 0010 0000 0000
930    5      >0800  = 0000 1000 0000 0000
931    6      >2000  = 0010 0000 0000 0000
932    7      >8000  = 1000 0000 0000 0000
933 
934******************************************************************************/
935 
936static DEVICE_START(ti99_pcb_pagedcru)
937{
938   /* device is ti99_cartslot:cartridge:pcb */
939   set_pointers(device, get_index_from_tagname(device->owner())-1);
940}
941 
942/*
943    Read handler for the CPU address space of the cartridge
944    Images for this area are found in the rom_sockets.
945*/
946static READ8Z_DEVICE_HANDLER( read_cart_pagedcru )
947{
948   /* device is pcb, owner is cartslot */
949   ti99_pcb_t *pcb = get_safe_pcb_token(device);
950   cartridge_t *cartridge = pcb->cartridge;
951 
952   if (cartridge->rom_ptr!=NULL)
953   {
954      *value = (cartridge->rom_ptr)[cartridge->rom_page*0x2000 + (offset & 0x1fff)];
955   }
956}
957 
958/*
959    This type of cartridge does not support writing to the EPROM address
960    space.
961*/
962static WRITE8_DEVICE_HANDLER( write_cart_pagedcru )
963{
964   return;
965}
966 
967/*
968    The CRU read handler. The CRU is a serial interface in the console.
969    Using the CRU we can switch the banks in the SuperSpace cartridge.
970    For documentation see the corresponding cru function above. Note we are
971    using rom_page here.
972*/
973static READ8Z_DEVICE_HANDLER( read_cart_cru_paged )
974{
975   ti99_pcb_t *pcb = get_safe_pcb_token(device);
976   cartridge_t *cartridge = pcb->cartridge;
977 
978   int page = cartridge->rom_page;
979   if ((offset & 0xf800)==0x0800)
980   {
981      int bit = (offset & 0x001e)/2;
982      if (bit != 0)
983      {
984         page = page-(bit/2);  // 4 page flags per 8 bits
985      }       
986      *value = 1 << (page*2+1);
987   }
988}
989 
990static WRITE8_DEVICE_HANDLER( write_cart_cru_paged )
991{
992   ti99_pcb_t *pcb = get_safe_pcb_token(device);
993   cartridge_t *cartridge = pcb->cartridge;
994 
995   if ((offset & 0xf800)==0x0800)
996   {
997      int bit = (offset & 0x001e)/2;
998      if (data != 0 && bit > 0)
999      {
1000         cartridge->rom_page = (bit-1)/2;
1001      }
1002   }
1003}
1004 
1005/*
1006    Pagedcru modules have one EPROM dump.
1007*/
1008static int assemble_pagedcru(running_device *image)
1009{
1010   cartridge_t *cart;
1011 
1012   cart = assemble_common(image);
1013   if (cart->rom_ptr==NULL)
1014   {
1015      logerror("Missing ROM for pagedcru cartridge");
1016      return IMAGE_INIT_FAIL;
1017   }
1018   cart->rom_page = 0;
1019   return IMAGE_INIT_PASS;
1020}
1021 
1022/*****************************************************************************
1023  Cartridge type: gramkracker
1024******************************************************************************/
1025 
1026static DEVICE_START(ti99_pcb_gramkracker)
1027{
1028   /* device is ti99_cartslot:cartridge:pcb */
1029//  printf("DEVICE_START(ti99_pcb_pagedcru), tag of device=%s\n", device->tag());
1030   set_pointers(device, get_index_from_tagname(device->owner())-1);
1031}
1032 
1033/*
1034    The GRAM Kracker contains one GROM and several buffered RAM chips
1035*/
1036static int assemble_gramkracker(running_device *image)
1037{
1038   cartridge_t *cart;
1039   int id,i;
1040 
1041   running_device *cartsys = image->owner();
1042   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1043 
1044   cart = assemble_common(image);
1045 
1046   if (cart->grom_ptr==NULL)
1047   {
1048      logerror("Missing loader GROM for GRAM Kracker system");
1049      return IMAGE_INIT_FAIL;
1050   }
1051 
1052   if (cart->ram_size < 81920)
1053   {
1054      logerror("Missing or insufficient RAM for GRAM Kracker system");
1055      return IMAGE_INIT_FAIL;
1056   }
1057 
1058   // Get slot number
1059   id = get_index_from_tagname(image);
1060   cartslots->gk_slot = id-1;
1061   cartslots->gk_guest_slot = -1;
1062   // The first cartridge that is still plugged in is the "guest" of the
1063   // GRAM Kracker
1064   for (i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++)
1065   {
1066      if (!slot_is_empty(cartsys, i) && (i != cartslots->gk_slot))
1067      {
1068         cartslots->gk_guest_slot = i;
1069         break;
1070      }
1071   }
1072   return IMAGE_INIT_PASS;
1073}
1074 
1075/*
1076    Unplugs the GRAM Kracker. The "guest" is still plugged in, but will be
1077    treated as normal.
1078*/
1079static int disassemble_gramkracker(running_device *cartslot)
1080{
1081   running_device *cartsys = cartslot->owner();
1082   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1083 
1084   //int slotnumber = get_index_from_tagname(cartslot)-1;
1085   //assert(slotnumber>=0 && slotnumber<NUMBER_OF_CARTRIDGE_SLOTS);
1086 
1087   cartslots->gk_slot = -1;
1088   cartslots->gk_guest_slot = -1;
1089 
1090   return disassemble_std(cartslot);
1091}
1092 
1093 
1094/*****************************************************************************
1095  Device metadata
1096******************************************************************************/
1097 
1098/*
1099   Get the pointer to the GROM data from the cartridge. Called by the GROM.
1100*/
1101static UINT8 *get_grom_ptr(running_device *device)
1102{
1103   ti99_pcb_t *pcb = get_safe_pcb_token(device);
1104   return pcb->cartridge->grom_ptr;
1105}
1106 
1107static MACHINE_CONFIG_FRAGMENT(ti99_cart_common)
1108   MDRV_GROM_ADD_P( "grom_3", 3, get_grom_ptr, 0x0000, 0x1800, cart_grom_ready )
1109   MDRV_GROM_ADD_P( "grom_4", 4, get_grom_ptr, 0x2000, 0x1800, cart_grom_ready )
1110   MDRV_GROM_ADD_P( "grom_5", 5, get_grom_ptr, 0x4000, 0x1800, cart_grom_ready )
1111   MDRV_GROM_ADD_P( "grom_6", 6, get_grom_ptr, 0x6000, 0x1800, cart_grom_ready )
1112   MDRV_GROM_ADD_P( "grom_7", 7, get_grom_ptr, 0x8000, 0x1800, cart_grom_ready )
1113MACHINE_CONFIG_END
1114 
1115static DEVICE_GET_INFO(ti99_cart_common)
1116{
1117   switch(state)
1118   {
1119      /* --- the following bits of info are returned as 64-bit signed integers --- */
1120      case DEVINFO_INT_TOKEN_BYTES:
1121         info->i = sizeof(ti99_pcb_t);
1122         break;
1123      case DEVINFO_INT_INLINE_CONFIG_BYTES:
1124         info->i = 0;
1125         break;
1126         
1127      case DEVINFO_PTR_MACHINE_CONFIG:       
1128         info->machine_config = MACHINE_CONFIG_NAME(ti99_cart_common);
1129         break;
1130 
1131      /* --- the following bits of info are returned as pointers to functions --- */
1132      case DEVINFO_FCT_START:
1133         info->start = DEVICE_START_NAME(ti99_pcb_std);
1134         break;
1135      case DEVINFO_FCT_STOP:
1136         /* Nothing */
1137         break;
1138      case DEVINFO_FCT_RESET:
1139         /* Nothing */
1140         break;
1141      case TI99CARTINFO_FCT_6000_R:
1142         info->f = (genf *) read_cart_std; break;
1143 
1144      case TI99CARTINFO_FCT_6000_W:
1145         info->f = (genf *) write_cart_std; break;
1146 
1147      case TI99CARTINFO_FCT_CRU_R:
1148         /* Nothing */
1149         break;
1150 
1151      case TI99CARTINFO_FCT_CRU_W:
1152         /* Nothing */
1153         break;
1154 
1155      case TI99CART_FCT_ASSM:
1156         info->f = (genf *) assemble_std;
1157         break;
1158 
1159      case TI99CART_FCT_DISASSM:
1160         info->f = (genf *) disassemble_std;
1161         break;
1162 
1163      /* --- the following bits of info are returned as NULL-terminated strings --- */
1164      case DEVINFO_STR_NAME:
1165         strcpy(info->s, "TI99 standard cartridge pcb");
1166         break;
1167      case DEVINFO_STR_FAMILY:
1168         strcpy(info->s, "TI99 cartridge pcb");
1169         break;
1170      case DEVINFO_STR_VERSION:
1171         strcpy(info->s, "1.0");
1172         break;
1173      case DEVINFO_STR_SOURCE_FILE:
1174         strcpy(info->s, __FILE__);
1175         break;
1176      case DEVINFO_STR_CREDITS:
1177         /* Nothing */
1178         break;
1179   }
1180}
1181 
1182DEVICE_GET_INFO(ti99_cartridge_pcb_none)
1183{
1184   switch(state)
1185   {
1186      case DEVINFO_FCT_START:
1187         info->start = DEVICE_START_NAME(ti99_pcb_none);
1188         break;
1189 
1190      case DEVINFO_STR_NAME:
1191         strcpy(info->s, "TI99 empty cartridge");
1192         break;
1193 
1194      // Don't create GROMs 
1195      case DEVINFO_PTR_MACHINE_CONFIG:       
1196         break;
1197         
1198      default:
1199         DEVICE_GET_INFO_CALL(ti99_cart_common);
1200         break;
1201   }
1202}
1203 
1204DEVICE_GET_INFO(ti99_cartridge_pcb_std)
1205{
1206   DEVICE_GET_INFO_CALL(ti99_cart_common);
1207}
1208 
1209DEVICE_GET_INFO(ti99_cartridge_pcb_paged)
1210{
1211   switch(state)
1212   {
1213      case DEVINFO_FCT_START:
1214         info->start = DEVICE_START_NAME(ti99_pcb_paged);
1215         break;
1216 
1217      case TI99CART_FCT_ASSM:
1218         info->f = (genf *) assemble_paged; 
1219         break;
1220 
1221      case TI99CARTINFO_FCT_6000_R:
1222         info->f = (genf *) read_cart_paged;
1223         break;
1224 
1225      case TI99CARTINFO_FCT_6000_W:
1226         info->f = (genf *) write_cart_paged;
1227         break;
1228 
1229      case DEVINFO_STR_NAME:
1230         strcpy(info->s, "TI99 paged cartridge pcb");
1231         break;
1232 
1233      default:
1234         DEVICE_GET_INFO_CALL(ti99_cart_common);
1235         break;
1236   }
1237}
1238 
1239DEVICE_GET_INFO(ti99_cartridge_pcb_minimem)
1240{
1241   switch(state)
1242   {
1243      case DEVINFO_FCT_START:
1244         info->start = DEVICE_START_NAME(ti99_pcb_minimem);
1245         break;
1246 
1247      case TI99CART_FCT_ASSM:
1248         info->f = (genf *) assemble_minimem;
1249         break;
1250      case TI99CARTINFO_FCT_6000_R:
1251         info->f = (genf *) read_cart_minimem;
1252         break;
1253      case TI99CARTINFO_FCT_6000_W:
1254         info->f = (genf *) write_cart_minimem;
1255         break;
1256         
1257      case DEVINFO_STR_NAME:
1258         strcpy(info->s, "TI99 MiniMemory cartridge pcb");
1259         break;
1260 
1261      default:
1262         DEVICE_GET_INFO_CALL(ti99_cart_common);
1263         break;
1264   }
1265}
1266 
1267DEVICE_GET_INFO(ti99_cartridge_pcb_super)
1268{
1269   switch(state)
1270   {
1271      case DEVINFO_FCT_START:
1272         info->start = DEVICE_START_NAME(ti99_pcb_super);
1273         break;
1274 
1275      case TI99CART_FCT_ASSM:
1276         info->f = (genf *) assemble_super;
1277         break;
1278      case TI99CARTINFO_FCT_6000_R:
1279         info->f = (genf *) read_cart_super;
1280         break;
1281      case TI99CARTINFO_FCT_6000_W:
1282         info->f = (genf *) write_cart_super;
1283         break;
1284      case TI99CARTINFO_FCT_CRU_R:
1285         info->f = (genf *) read_cart_cru;
1286         break;
1287      case TI99CARTINFO_FCT_CRU_W:
1288         info->f = (genf *) write_cart_cru;
1289         break;
1290 
1291      // Don't create GROMs 
1292      case DEVINFO_PTR_MACHINE_CONFIG:       
1293         break;
1294 
1295      case DEVINFO_STR_NAME:
1296         strcpy(info->s, "TI99 SuperSpace cartridge pcb");
1297         break;
1298 
1299      default:
1300         DEVICE_GET_INFO_CALL(ti99_cart_common);
1301         break;
1302   }
1303}
1304 
1305DEVICE_GET_INFO(ti99_cartridge_pcb_mbx)
1306{
1307   switch(state)
1308   {
1309      case DEVINFO_FCT_START:
1310         info->start = DEVICE_START_NAME(ti99_pcb_mbx);
1311         break;
1312 
1313      case TI99CART_FCT_ASSM:
1314         info->f = (genf *) assemble_mbx;
1315         break;
1316      case TI99CARTINFO_FCT_6000_R:
1317         info->f = (genf *) read_cart_mbx;
1318         break;
1319      case TI99CARTINFO_FCT_6000_W:
1320         info->f = (genf *) write_cart_mbx;
1321         break;
1322 
1323      case DEVINFO_STR_NAME:
1324         strcpy(info->s, "TI99 MBX cartridge pcb");
1325         break;
1326 
1327      default:
1328         DEVICE_GET_INFO_CALL(ti99_cart_common);
1329         break;
1330   }
1331}
1332 
1333DEVICE_GET_INFO(ti99_cartridge_pcb_paged379i)
1334{
1335   switch(state)
1336   {
1337      case DEVINFO_FCT_START:
1338         info->start = DEVICE_START_NAME(ti99_pcb_paged379i);
1339         break;
1340 
1341      case TI99CART_FCT_ASSM:
1342         info->f = (genf *) assemble_paged379i; break;
1343 
1344      case TI99CARTINFO_FCT_6000_R:
1345         info->f = (genf *) read_cart_paged379i;
1346         break;
1347 
1348      case TI99CARTINFO_FCT_6000_W:
1349         info->f = (genf *) write_cart_paged379i;
1350         break;
1351 
1352      case DEVINFO_STR_NAME:
1353         strcpy(info->s, "TI99 paged379i cartridge pcb");
1354         break;
1355 
1356      default:
1357         DEVICE_GET_INFO_CALL(ti99_cart_common);
1358         break;
1359   }
1360}
1361 
1362DEVICE_GET_INFO(ti99_cartridge_pcb_pagedcru)
1363{
1364   switch(state)
1365   {
1366      case DEVINFO_FCT_START:
1367         info->start = DEVICE_START_NAME(ti99_pcb_pagedcru);
1368         break;
1369 
1370      case TI99CART_FCT_ASSM:
1371         info->f = (genf *) assemble_pagedcru;
1372         break;
1373 
1374      case TI99CARTINFO_FCT_6000_R:
1375         info->f = (genf *) read_cart_pagedcru;
1376         break;
1377 
1378      case TI99CARTINFO_FCT_6000_W:
1379         info->f = (genf *) write_cart_pagedcru;
1380         break;
1381 
1382      case TI99CARTINFO_FCT_CRU_R:
1383         info->f = (genf *) read_cart_cru_paged;
1384         break;
1385      case TI99CARTINFO_FCT_CRU_W:
1386         info->f = (genf *) write_cart_cru_paged;
1387         break;
1388 
1389      case DEVINFO_STR_NAME:
1390         strcpy(info->s, "TI99 pagedcru cartridge pcb");
1391         break;
1392 
1393      default:
1394         DEVICE_GET_INFO_CALL(ti99_cart_common);
1395         break;
1396   }
1397}
1398 
1399DEVICE_GET_INFO(ti99_cartridge_pcb_gramkracker)
1400{
1401   switch(state)
1402   {
1403      case DEVINFO_FCT_START:
1404         info->start = DEVICE_START_NAME(ti99_pcb_gramkracker);
1405         break;
1406 
1407      case TI99CART_FCT_ASSM:
1408         info->f = (genf *) assemble_gramkracker;
1409         break;
1410 
1411      case TI99CART_FCT_DISASSM:
1412         info->f = (genf *) disassemble_gramkracker;
1413         break;
1414 
1415      case DEVINFO_STR_NAME:
1416         strcpy(info->s, "TI99 GRAM Kracker system");
1417         break;
1418 
1419      default:
1420         DEVICE_GET_INFO_CALL(ti99_cart_common);
1421         break;
1422   }
1423}
1424 
1425/*****************************************************************************
1426  The cartridge handling of the multi-cartridge system.
1427  Every cartridge contains a PCB device. The memory handlers delegate the calls
1428  to the respective handlers of the cartridges.
1429******************************************************************************/
1430/*
1431    Initialize a cartridge. Each cartridge contains a PCB device.
1432*/
1433static DEVICE_START( ti99_cartridge )
1434{
1435   cartslot_t *cart = (cartslot_t *)downcast<legacy_device_base *>(device)->token();
1436 
1437   /* find the PCB device */
1438   cart->pcb_device = device->subdevice(TAG_PCB);
1439}
1440 
1441/*
1442    Load the cartridge image files. Apart from reading, we set pointers
1443    to the image files so that during runtime we do not need search
1444    operations.
1445*/
1446static DEVICE_IMAGE_LOAD( ti99_cartridge )
1447{
1448   running_device *pcbdev = cartslot_get_pcb(&image.device());
1449//   running_device *cartsys = image.device().owner();
1450//   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1451 
1452   int result;
1453 
1454   if (pcbdev != NULL)
1455   {
1456      /* If we are here, we have a multicart. */
1457      ti99_pcb_t *pcb = (ti99_pcb_t *)downcast<legacy_device_base *>(pcbdev)->token();
1458      cartslot_t *cart = (cartslot_t *)downcast<legacy_device_base *>(&image.device())->token();
1459 
1460      /* try opening this as a multicart */
1461      // This line requires that cartslot_t be included in cartslot.h,
1462      // otherwise one cannot make use of multicart handling within such a
1463      // custom LOAD function.
1464      multicart_open_error me = multicart_open(image.filename(), image.device().machine->gamedrv->name, MULTICART_FLAGS_LOAD_RESOURCES, &cart->mc);
1465 
1466      // Now that we have loaded the image files, let the PCB put them all
1467      // together. This means we put the images in a structure which allows
1468      // for a quick access by the memory handlers. Every PCB defines an
1469      // own assembly method.
1470      if (me == MCERR_NONE)
1471         result = pcb->assemble(image);
1472      else
1473         fatalerror("Error loading multicart: %s", multicart_error_text(me));
1474   }
1475   else
1476   {
1477      fatalerror("Error loading multicart: no pcb found.");
1478   }
1479   return result;
1480}
1481 
1482/*
1483    This is called when the cartridge is unplugged (or the emulator is
1484    stopped).
1485*/
1486static DEVICE_IMAGE_UNLOAD( ti99_cartridge )
1487{
1488   running_device *pcbdev;
1489//   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(image.device().owner())->token();
1490 
1491   if (downcast<legacy_device_base *>(&image.device())->token() == NULL)
1492   {
1493      // This means something went wrong during the pcb
1494      // identification (e.g. one of the cartridge files was not
1495      // found). We do not need to (and cannot) unload the cartridge.
1496      return;
1497   }
1498   pcbdev = cartslot_get_pcb(image);
1499 
1500   if (pcbdev != NULL)
1501   {
1502      ti99_pcb_t *pcb = (ti99_pcb_t *)downcast<legacy_device_base *>(pcbdev)->token();
1503      cartslot_t *cart = (cartslot_t *)downcast<legacy_device_base *>(&image.device())->token();
1504 
1505      if (cart->mc != NULL)
1506      {
1507         /* Remove pointers and de-big-endianize RAM contents. */
1508         pcb->disassemble(image);
1509 
1510         // Close the multicart; all RAM resources will be
1511         // written to disk
1512         multicart_close(cart->mc);
1513         cart->mc = NULL;
1514 
1515      }
1516   }
1517}
1518 
1519/*****************************************************************************
1520  The overall multi-cartridge slot system. It contains instances of
1521  cartridges which contain PCB devices. The memory handlers delegate the calls
1522  to the respective handlers of the cartridges.
1523 
1524  Note that the term "multi-cartridge system" and "multicart" are not the same:
1525  A "multicart" may contain multiple resources, organized on a PCB. The multi-
1526  cart system may thus host multiple multicarts.
1527 
1528  Actually, the name of the device should be changed (however, the device name
1529  length is limited)
1530******************************************************************************/
1531 
1532static READ8Z_DEVICE_HANDLER( ti99_cart_gk_rz );
1533static WRITE8_DEVICE_HANDLER( ti99_cart_gk_w );
1534static void cartridge_gram_kracker_writeg(running_device *cartsys, int offset, UINT8 data);
1535static void cartridge_gram_kracker_readg(running_device *device, UINT8 *value);
1536static READ8Z_DEVICE_HANDLER( ti99_cart_cru_gk_rz );
1537static WRITE8_DEVICE_HANDLER( ti99_cart_cru_gk_w );
1538 
1539/*
1540    Instantiation of a multicart system for the TI family.
1541*/
1542static DEVICE_START(ti99_multicart)
1543{
1544   int i;
1545   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1546   const ti99_multicart_config* cartconf = (const ti99_multicart_config*)get_config(device);
1547 
1548   cartslots->active_slot = 0;
1549   cartslots->next_free_slot = 0;
1550 
1551   for (i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++)
1552   {
1553      cartslots->cartridge[i].pcb = NULL;
1554      clear_slot(device, i);
1555   }
1556   
1557   devcb_write_line ready = DEVCB_LINE(cartconf->ready);
1558 
1559   devcb_resolve_write_line(&cartslots->ready, &ready, device);
1560   
1561   // The cartslot system is initialized now. The cartridges themselves
1562   // need to check whether their parts are available.
1563}
1564 
1565static DEVICE_STOP(ti99_multicart)
1566{
1567//  printf("DEVICE_STOP(ti99_multicart)\n");
1568}
1569 
1570static DEVICE_RESET(ti99_multicart)
1571{
1572   // Consider to propagate RESET to cartridges.
1573   // However, schematics do not reveal any pin for resetting a cartridge;
1574   // the reset line is an input used when plugging in a cartridge.
1575 
1576   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1577   int slotnumber = input_port_read(device->machine, "CARTSLOT");
1578   cartslots->fixed_slot = slotnumber-1; /* auto = -1 */
1579}
1580 
1581/*
1582    Accesses the ROM regions of the cartridge for reading.
1583*/
1584READ8Z_DEVICE_HANDLER( gromportr_rz )
1585{
1586   ti99_multicart_state *cartslots = (ti99_multicart_state *) downcast<legacy_device_base *>(device)->token();
1587   int slot = cartslots->active_slot;
1588   cartridge_t *cart;
1589 
1590   // Handle GRAM Kracker
1591   // We could also consider to use a flag, but input_port_read uses
1592   // a hashtable, so this should not be too slow
1593   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1594   {
1595      ti99_cart_gk_rz(device, offset, value);
1596      return;
1597   }
1598   
1599   /* Sanity check. Higher slots are always empty. */
1600   if (slot >= NUMBER_OF_CARTRIDGE_SLOTS)
1601      return;
1602 
1603   // Same as above (GROM read)
1604   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1605      slot=0;
1606 
1607   cart = &cartslots->cartridge[slot];
1608 
1609   if (!slot_is_empty(device, slot))
1610   {
1611//      printf("try it on slot %d\n", slot);
1612      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cart->pcb)->token();
1613      (*pcbdef->read)(cart->pcb, offset, value);
1614   }
1615}
1616 
1617/*
1618    Accesses the ROM regions of the cartridge for writing.
1619*/
1620WRITE8_DEVICE_HANDLER( gromportr_w )
1621{
1622   ti99_multicart_state *cartslots = (ti99_multicart_state *) downcast<legacy_device_base *>(device)->token();
1623   int slot = cartslots->active_slot;
1624   cartridge_t *cart;
1625 
1626   // Handle GRAM Kracker
1627   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1628      ti99_cart_gk_w(device, offset, data);
1629 
1630   /* Sanity check. Higher slots are always empty. */
1631   if (slot >= NUMBER_OF_CARTRIDGE_SLOTS)
1632      return;
1633 
1634   /* Same as above (READ16). */
1635   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1636      slot=0;
1637 
1638   cart = &cartslots->cartridge[slot];
1639 
1640   if (!slot_is_empty(device, slot))
1641   {
1642      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cart->pcb)->token();
1643      (*pcbdef->write)(cart->pcb, offset, data);
1644   }
1645}
1646 
1647/*
1648    Set the address pointer value or write to GRAM (if available).
1649*/
1650WRITE8_DEVICE_HANDLER(gromportg_w)
1651{
1652   int slot;
1653   cartridge_t *cartridge;
1654   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1655 
1656   // Set the cart slot.
1657   // 1001 1wbb bbbb bbr0
1658 
1659   cartridge_slot_set(device, (UINT8)((offset>>2) & 0x00ff));
1660   slot = cartslots->active_slot;
1661 
1662   // The selection mechanism of the console checks the different GROM address
1663   // bases, and when it finds different data, it concludes that there is 
1664   // indeed a multi-cartridge facility. Empty   slots return 0 at all 
1665   // addresses.
1666   // Unfortunately, TI's cartridge selection mechanism has an undesirable 
1667   // side-effect which we work around in this implementation.
1668   // When we have only one cartridge we would like to get only the option to
1669   // select this cartridge and not an option to switch to the next one (which
1670   // would immediately cycle back to cartridge 1). However, the console 
1671   // routines always show the switch option when any two slots have different
1672   // content, and this is the case with only one cartridge (slot 2 will then
1673   // be filled with zeros).
1674   // So if next_free_slot==1, we have one cartridge in slot 0.
1675   // In that case we trick the OS to believe that the addressed
1676   // cartridge appears at all locations which causes it to assume a
1677   // standard single cartslot.
1678 
1679   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1680      slot=0;
1681 
1682   // Handle the GRAM Kracker
1683   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1684   {
1685      cartridge_gram_kracker_writeg(device, offset, data);
1686      return;
1687   }
1688 
1689   if (slot < NUMBER_OF_CARTRIDGE_SLOTS)
1690   {
1691      cartridge = &cartslots->cartridge[slot];
1692      // Send the request to all mounted GROMs
1693      if (cartridge->pcb!=NULL)
1694      {
1695         for (int i=0; i < 5; i++)
1696         {
1697            ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cartridge->pcb)->token();
1698            if (pcbdef->grom[i]!=NULL)
1699               ti99grom_w(pcbdef->grom[i], offset, data);
1700         }
1701      }
1702   }
1703}
1704 
1705/*
1706    GROM access. Nota bene: We only react to the request if there is a GROM
1707    at the selected bank with the currently selected ID. If not, just do
1708    nothing; do not return a value.
1709    (We must not return a value since all GROMs are connected in parallel, so
1710    returning a 0, for instance, will spoil the processing of other GROMs.)
1711*/
1712READ8Z_DEVICE_HANDLER(gromportg_rz)
1713{
1714   int slot;
1715   cartridge_t *cartridge;
1716   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1717 
1718   // Set the cart slot. Note that the port must be adjusted for 16-bit
1719   // systems, i.e. it should be shifted left by 1.
1720   // 1001 1wbb bbbb bbr0
1721 
1722   cartridge_slot_set(device, (UINT8)((offset>>2) & 0x00ff));
1723   
1724   // Handle the GRAM Kracker
1725   // BTW, the GK does not have a readable address counter, but the console 
1726   // GROMs will keep our addess counter up to date. That is
1727   // exactly what happens in the real machine.
1728   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1729   {
1730      if ((offset & 0x0002)==0) cartridge_gram_kracker_readg(device, value);
1731      return;
1732   }
1733 
1734   slot = cartslots->active_slot;
1735   
1736   // This fixes a minor issue: The selection mechanism of the console
1737   // concludes that there are multiple cartridges plugged in when it
1738   // checks the different GROM bases and finds different data. Empty
1739   // slots should return 0 at all addresses, but when we have only
1740   // one cartridge, this entails that the second cartridge is
1741   // different (all zeros), and so we get a meaningless selection
1742   // option between cartridge 1 and 1 and 1 ...
1743   //
1744   // So if next_free_slot==1, we have one cartridge in slot 0.
1745   // In that case we trick the OS to believe that the addressed
1746   // cartridge appears at all locations which causes it to assume a
1747   // standard single cartslot.
1748   
1749   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1750      slot=0;
1751   
1752   if (slot < NUMBER_OF_CARTRIDGE_SLOTS)
1753   {
1754      // Select the cartridge which the multicart system is currently pointing at
1755      cartridge = &cartslots->cartridge[slot];
1756      // Send the request to all mounted GROMs on this PCB
1757      if (cartridge->pcb!=NULL)
1758      {
1759         for (int i=0; i < 5; i++)
1760         {
1761            ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cartridge->pcb)->token();
1762            if (pcbdef->grom[i]!=NULL)
1763               ti99grom_rz(pcbdef->grom[i], offset, value);
1764         }
1765      }
1766   }
1767}
1768 
1769/*
1770    CRU interface to cartridges, used only by SuperSpace and Pagedcru
1771    style cartridges.
1772    The SuperSpace has a CRU-based memory mapper. It is accessed via the
1773    cartridge slot on CRU base >0800.
1774*/
1775READ8Z_DEVICE_HANDLER( gromportc_rz )
1776{
1777   ti99_multicart_state *cartslots = (ti99_multicart_state *) downcast<legacy_device_base *>(device)->token();
1778   cartridge_t *cart;
1779 
1780   int slot = cartslots->active_slot;
1781 
1782   // Handle GRAM Kracker
1783   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1784   {
1785      ti99_cart_cru_gk_rz(device, offset, value);
1786      return;
1787   }
1788   
1789   /* Sanity check. Higher slots are always empty. */
1790   if (slot >= NUMBER_OF_CARTRIDGE_SLOTS)
1791      return;
1792 
1793   /* Same as above (READ16). */
1794   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1795      slot=0;
1796 
1797   cart = &cartslots->cartridge[slot];
1798 
1799   if (!slot_is_empty(device, slot))
1800   {
1801      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cart->pcb)->token();;
1802      if (pcbdef->cruread != NULL)
1803         (*pcbdef->cruread)(cart->pcb, offset, value);
1804   }
1805}
1806 
1807/*
1808    Write cartridge mapper CRU interface (SuperSpace, Pagedcru)
1809*/
1810WRITE8_DEVICE_HANDLER( gromportc_w )
1811{
1812   ti99_multicart_state *cartslots = (ti99_multicart_state *) downcast<legacy_device_base *>(device)->token();
1813   cartridge_t *cart;
1814 
1815   int slot = cartslots->active_slot;
1816 
1817   // Handle GRAM Kracker
1818   if ((cartslots->gk_slot != -1) && (input_port_read(device->machine, "CARTSLOT")==CART_GK))
1819   {
1820      ti99_cart_cru_gk_w(device, offset, data);
1821      return;
1822   }
1823   
1824   /* Sanity check. Higher slots are always empty. */
1825   if (slot >= NUMBER_OF_CARTRIDGE_SLOTS)
1826      return;
1827 
1828   /* Same as above (READ16). */
1829   if (cartslots->fixed_slot==AUTO && cartslots->next_free_slot==1)
1830      slot=0;
1831 
1832   cart = &cartslots->cartridge[slot];
1833 
1834   if (!slot_is_empty(device, slot))
1835   {
1836      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(cart->pcb)->token();;
1837      if (pcbdef->cruwrite != NULL)
1838         (*pcbdef->cruwrite)(cart->pcb, offset, data);
1839   }
1840}
1841 
1842/*****************************************************************************
1843   GramKracker support
1844   The 80 KiB of the GK are allocated as follows
1845   00000 - 01fff: GRAM 0
1846   02000 - 03fff: GRAM 1  (alternatively, the loader GROM appears here)
1847   04000 - 05fff: GRAM 2
1848   06000 - 0ffff: GRAM 3-7 (alternatively, the guest GROMs appear here)
1849   10000 - 11fff: RAM 1
1850   12000 - 13fff: RAM 2
1851   
1852   The GK emulates GROMs, but without a readable address counter. Thus it
1853   relies on the console GROMs being still in place (compare with the HSGPL).
1854   Also, the GK does not implement a GROM buffer.
1855******************************************************************************/
1856 
1857/*
1858    Reads from the GRAM space of the GRAM Kracker.
1859*/
1860static void cartridge_gram_kracker_readg(running_device *cartsys, UINT8 *value)
1861{
1862   // gk_slot is the slot where the GK module is plugged in
1863   // gk_guest_slot is the slot where the cartridge is plugged in
1864 
1865   cartridge_t *gromkrackerbox, *gkguestcart;
1866   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1867 
1868   // Not null, since this is only called when there is really a GK module
1869   gromkrackerbox = &cartslots->cartridge[cartslots->gk_slot];
1870 
1871   if ((gromkrackerbox->grom_address & 0xe000) == 0x0000)
1872   {
1873      // GRAM 0. Only return a value if switch 2 is in GRAM0 position.
1874      if (get_gk_switch(cartsys, 2)==GK_GRAM0)
1875         *value = (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address];
1876   }
1877   
1878   if ((gromkrackerbox->grom_address & 0xe000) == 0x2000)
1879   {
1880      // If the loader is turned on, return loader contents.
1881      if (get_gk_switch(cartsys, 5)==GK_LDON)
1882      {
1883         // The only ROM contained in the GK box is the loader
1884         *value = gromkrackerbox->grom_ptr[gromkrackerbox->grom_address & 0x1fff];
1885      }
1886      else
1887      {
1888         // Loader off
1889         // GRAM 1. Only return a value if switch 3 is in GRAM12 position.
1890         if (get_gk_switch(cartsys, 3)==GK_GRAM12)
1891            *value = (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address];
1892      }
1893   }
1894 
1895   if ((gromkrackerbox->grom_address & 0xe000) == 0x4000)
1896   {
1897      // GRAM 2. Only return a value if switch 3 is in GRAM12 position.
1898      if (get_gk_switch(cartsys, 3)==GK_GRAM12)
1899         *value = (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address];
1900   }
1901 
1902   if (((gromkrackerbox->grom_address & 0xe000) == 0x6000) || 
1903      ((gromkrackerbox->grom_address & 0x8000) == 0x8000))
1904   {
1905      // Cartridge space
1906      // When a cartridge is installed, it overrides the GK contents
1907      // but only if it has GROMs       
1908      int cartwithgrom = FALSE;
1909      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
1910 
1911      // Send the request to all mounted GROMs
1912      if (gkguestcart->pcb!=NULL)
1913      {
1914         for (int i=0; i < 5; i++)
1915         {
1916            ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
1917            if (pcbdef->grom[i]!=NULL)
1918            {
1919               ti99grom_rz(pcbdef->grom[i], 0x9800, value);
1920               cartwithgrom = TRUE;
1921            }
1922         }
1923      }
1924      if (!cartwithgrom && get_gk_switch(cartsys, 1)==GK_NORMAL)
1925      {
1926         *value = (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address];         
1927      }
1928   }
1929 
1930   // The GK GROM emulation does not wrap at 8K boundaries.
1931   gromkrackerbox->grom_address = (gromkrackerbox->grom_address+1) & 0xffff;
1932 
1933   /* Reset the write address flipflop. */
1934   gromkrackerbox->waddr_LSB = FALSE;
1935}
1936 
1937/*
1938    Writes to the GRAM space of the GRAM Kracker.
1939*/
1940static void cartridge_gram_kracker_writeg(running_device *cartsys, int offset, UINT8 data)
1941{
1942   // gk_slot is the slot where the GK module is plugged in
1943   // gk_guest_slot is the slot where the cartridge is plugged in
1944   cartridge_t *gromkrackerbox;
1945   ti99_multicart_state *cartslots = get_safe_token(cartsys);
1946 
1947   // This is only called when there is really a GK module
1948   gromkrackerbox = &cartslots->cartridge[cartslots->gk_slot];
1949 
1950   if ((offset & 0x0002)==0x0002)
1951   {
1952      // Set address       
1953      if (gromkrackerbox->waddr_LSB)
1954      {
1955         /* Accept low byte (2nd write) */
1956         gromkrackerbox->grom_address = (gromkrackerbox->grom_address & 0xff00) | data;
1957         gromkrackerbox->waddr_LSB = FALSE;
1958      }
1959      else
1960      {
1961         /* Accept high byte (1st write) */
1962         gromkrackerbox->grom_address = ((data<<8) & 0xff00) | (gromkrackerbox->grom_address & 0x00ff);
1963         gromkrackerbox->waddr_LSB = TRUE;
1964      }
1965   }
1966   else
1967   {
1968      if (get_gk_switch(cartsys, 4) != GK_WP)
1969      {
1970         // Write protection off
1971         if (   (((gromkrackerbox->grom_address & 0xe000)==0x0000) && get_gk_switch(cartsys, 2)==GK_GRAM0)
1972            || (((gromkrackerbox->grom_address & 0xe000)==0x2000) && get_gk_switch(cartsys, 3)==GK_GRAM12 && (get_gk_switch(cartsys, 5)==GK_LDOFF))
1973            || (((gromkrackerbox->grom_address & 0xe000)==0x4000) && get_gk_switch(cartsys, 3)==GK_GRAM12)
1974            || (((gromkrackerbox->grom_address & 0xe000)==0x6000) && get_gk_switch(cartsys, 1)==GK_NORMAL && (cartslots->gk_guest_slot==-1))
1975            || (((gromkrackerbox->grom_address & 0x8000)==0x8000) && get_gk_switch(cartsys, 1)==GK_NORMAL && (cartslots->gk_guest_slot==-1))) 
1976         {
1977            (gromkrackerbox->ram_ptr)[gromkrackerbox->grom_address] = data;
1978         }
1979      }
1980      // The GK GROM emulation does not wrap at 8K boundaries.
1981      gromkrackerbox->grom_address = (gromkrackerbox->grom_address+1) & 0xffff;
1982       
1983      /* Reset the write address flipflop. */
1984      gromkrackerbox->waddr_LSB = FALSE;
1985   }
1986}
1987 
1988/*
1989    Reads from the RAM space of the GRAM Kracker.
1990*/
1991static READ8Z_DEVICE_HANDLER( ti99_cart_gk_rz )
1992{
1993   // gk_slot is the slot where the GK module is plugged in
1994   // gk_guest_slot is the slot where the cartridge is plugged in
1995   cartridge_t *gromkrackerbox, *gkguestcart;
1996   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
1997 
1998   gromkrackerbox = &cartslots->cartridge[cartslots->gk_slot];
1999 
2000   if (cartslots->gk_guest_slot != -1)
2001   {
2002      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
2003      // Legacy mode is not supported with the GK
2004      if (in_legacy_mode(device))
2005      {
2006         return;
2007      }
2008      //      printf("accessing cartridge in slot %d\n", slot);
2009      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
2010      //      printf("address=%lx, offset=%lx\n", pcbdef, offset);
2011      (*pcbdef->read)(gkguestcart->pcb, offset, value);
2012      return;
2013   }
2014   else
2015   {
2016      if (get_gk_switch(device, 1)==GK_OFF) return;
2017      if (get_gk_switch(device, 4)==GK_BANK1)
2018      {
2019         *value = (gromkrackerbox->ram_ptr)[offset+0x10000];
2020      }
2021      else
2022      {
2023         if (get_gk_switch(device, 4)==GK_BANK2)
2024         {
2025            *value = (gromkrackerbox->ram_ptr)[offset+0x12000];
2026         }
2027         else
2028         {
2029            // Write protection on; auto-bank
2030            if (gromkrackerbox->ram_page==0)
2031            {
2032               *value = (gromkrackerbox->ram_ptr)[offset+0x10000];
2033            }
2034            else
2035            {
2036               *value = (gromkrackerbox->ram_ptr)[offset+0x12000];
2037            }
2038         }
2039      }
2040   }
2041}
2042 
2043/*
2044    Writes to the RAM space of the GRAM Kracker.
2045*/
2046static WRITE8_DEVICE_HANDLER( ti99_cart_gk_w )
2047{
2048   // gk_slot is the slot where the GK module is plugged in
2049   // gk_guest_slot is the slot where the cartridge is plugged in
2050   cartridge_t *gromkrackerbox, *gkguestcart;
2051   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
2052 
2053   gromkrackerbox = &cartslots->cartridge[cartslots->gk_slot];
2054 
2055   if (cartslots->gk_guest_slot != -1)
2056   {
2057      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
2058      // Legacy mode is not supported with the GK
2059      if (in_legacy_mode(device))
2060      {
2061         return;
2062      }
2063 
2064      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
2065         (*pcbdef->write)(gkguestcart->pcb, offset, data);
2066   }
2067   else
2068   {
2069      if (get_gk_switch(device, 1)==GK_OFF)
2070         return;
2071 
2072      if (get_gk_switch(device, 4)==GK_BANK1)
2073      {
2074         (gromkrackerbox->ram_ptr)[offset + 0x10000] = data;
2075      }
2076      else
2077      {
2078         if (get_gk_switch(device, 4)==GK_BANK2)
2079         {
2080            (gromkrackerbox->ram_ptr)[offset + 0x12000] = data;
2081         }
2082         else
2083         {
2084            // Write protection on
2085            // This is handled like in Extended Basic
2086            gromkrackerbox->ram_page = (offset & 2)>>1;
2087         }
2088      }
2089   }
2090}
2091 
2092/*
2093    Read cartridge mapper CRU interface (Guest in GRAM Kracker)
2094*/
2095static READ8Z_DEVICE_HANDLER( ti99_cart_cru_gk_rz )
2096{
2097   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
2098   cartridge_t *gkguestcart;
2099 
2100   if (cartslots->gk_guest_slot != -1)
2101   {
2102      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
2103      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
2104      if (pcbdef->cruread != NULL)
2105         (*pcbdef->cruread)(gkguestcart->pcb, offset, value);
2106   }
2107}
2108 
2109/*
2110    Write cartridge mapper CRU interface (Guest in GRAM Kracker)
2111*/
2112static WRITE8_DEVICE_HANDLER( ti99_cart_cru_gk_w )
2113{
2114   ti99_multicart_state *cartslots = (ti99_multicart_state *)downcast<legacy_device_base *>(device)->token();
2115   cartridge_t *gkguestcart;
2116 
2117   if (cartslots->gk_guest_slot != -1)
2118   {
2119      gkguestcart = &cartslots->cartridge[cartslots->gk_guest_slot];
2120      ti99_pcb_t *pcbdef = (ti99_pcb_t *)downcast<legacy_device_base *>(gkguestcart->pcb)->token();
2121      if (pcbdef->cruwrite != NULL)
2122         (*pcbdef->cruwrite)(gkguestcart->pcb, offset, data);
2123   }
2124}
2125 
2126/*****************************************************************************/
2127#define TI99_CARTRIDGE_SLOT(p)  MDRV_CARTSLOT_ADD(p) \
2128   MDRV_CARTSLOT_EXTENSION_LIST("rpk,bin") \
2129   MDRV_CARTSLOT_PCBTYPE(0, "none", TI99_CARTRIDGE_PCB_NONE) \
2130   MDRV_CARTSLOT_PCBTYPE(1, "standard", TI99_CARTRIDGE_PCB_STD) \
2131   MDRV_CARTSLOT_PCBTYPE(2, "paged", TI99_CARTRIDGE_PCB_PAGED) \
2132   MDRV_CARTSLOT_PCBTYPE(3, "minimem", TI99_CARTRIDGE_PCB_MINIMEM) \
2133   MDRV_CARTSLOT_PCBTYPE(4, "super", TI99_CARTRIDGE_PCB_SUPER) \
2134   MDRV_CARTSLOT_PCBTYPE(5, "mbx", TI99_CARTRIDGE_PCB_MBX) \
2135   MDRV_CARTSLOT_PCBTYPE(6, "paged379i", TI99_CARTRIDGE_PCB_PAGED379I) \
2136   MDRV_CARTSLOT_PCBTYPE(7, "pagedcru", TI99_CARTRIDGE_PCB_PAGEDCRU) \
2137   MDRV_CARTSLOT_PCBTYPE(8, "gramkracker", TI99_CARTRIDGE_PCB_GRAMKRACKER) \
2138   MDRV_CARTSLOT_START(ti99_cartridge) \
2139   MDRV_CARTSLOT_LOAD(ti99_cartridge) \
2140   MDRV_CARTSLOT_UNLOAD(ti99_cartridge)
2141 
2142static MACHINE_CONFIG_FRAGMENT(ti99_multicart)
2143   TI99_CARTRIDGE_SLOT("cartridge1")
2144   TI99_CARTRIDGE_SLOT("cartridge2")
2145   TI99_CARTRIDGE_SLOT("cartridge3")
2146   TI99_CARTRIDGE_SLOT("cartridge4")
2147MACHINE_CONFIG_END
2148 
2149static const char DEVTEMPLATE_SOURCE[] = __FILE__;
2150 
2151#define DEVTEMPLATE_ID(p,s)             p##ti99_multicart##s
2152#define DEVTEMPLATE_FEATURES            DT_HAS_START | DT_HAS_STOP | DT_HAS_RESET | DT_HAS_INLINE_CONFIG | DT_HAS_MACHINE_CONFIG
2153#define DEVTEMPLATE_NAME                "TI99 Multi-Cartridge Extender"
2154#define DEVTEMPLATE_FAMILY              "Multi-cartridge system"
2155#include "devtempl.h"
2156 
2157DEFINE_LEGACY_CART_SLOT_DEVICE(TI99_MULTICART, ti99_multicart);
src/mess/machine/ti99/tn_ide.c
r9488r9489
1/*
2    Thierry Nouspikel's IDE card emulation
3
4    This card is just a prototype.  It has been designed by Thierry Nouspikel,
5    and its description was published in 2001.  The card have been revised in
6    2004.
7
8    The specs have been published in <http://www.nouspikel.com/ti99/ide.html>.
9
10    The IDE interface is quite simple, since it only implements PIO transfer.
11    The card includes a clock chip to timestamp files, and an SRAM for the DSR.
12    It should be possible to use a battery backed DSR SRAM, but since the clock
13    chip includes 4kb of battery-backed RAM, a bootstrap loader can be saved in
14    the clock SRAM in order to load the DSR from the HD when the computer
15    starts.
16
17    Raphael Nabet, 2002-2004.
18
19    Rewritten as device
20    Michael Zapf, September 2010
21   
22    FIXME: idecont assumes that there is only one drive that is called
23    "harddisk" at the root level
24*/
25#include "emu.h"
26#include "peribox.h"
27#include "machine/idectrl.h"
28#include "machine/rtc65271.h"
29#include "machine/idectrl.h"
30#include "cpu/tms9900/tms9900.h"
31#include "tn_ide.h"
32
33#define CRU_BASE 0x1000
34
35typedef ti99_pebcard_config tn_ide_config;
36
37enum
38{   /* 0xff for 2 mbytes, 0x3f for 512kbytes, 0x03 for 32 kbytes */
39   page_mask = /*0xff*/0x3f
40};
41
42enum
43{
44   cru_reg_page_switching = 0x04,
45   cru_reg_page_0 = 0x08,
46   /*cru_reg_rambo = 0x10,*/   /* not emulated */
47   cru_reg_wp = 0x20,
48   cru_reg_int_en = 0x40,
49   cru_reg_reset = 0x80
50};
51
52typedef struct _tn_ide_state
53{
54   int    selected;
55
56   running_device      *rtc;
57   running_device      *ide;
58
59   int      ide_irq;
60   int      clk_irq;
61   int    sram_enable;
62   int    sram_enable_dip;
63   int    cru_register;
64   int      cur_page;
65   
66   int      tms9995_mode;
67   
68   UINT8    input_latch;
69   UINT8    output_latch;
70   
71   UINT8   *ram;
72   
73   /* Callback lines to the main system. */
74   ti99_peb_connect   lines;
75   
76} tn_ide_state;
77
78INLINE tn_ide_state *get_safe_token(running_device *device)
79{
80   assert(device != NULL);
81   return (tn_ide_state *)downcast<legacy_device_base *>(device)->token();
82}
83
84
85/*
86    CRU read
87*/
88static READ8Z_DEVICE_HANDLER( cru_rz )
89{
90   tn_ide_state *card = get_safe_token(device);
91   UINT8 reply;
92   if ((offset & 0xff00)==CRU_BASE)
93   {
94      int bit = (offset >> 4) & 7;
95     
96      if (bit==0)
97      {
98         reply = card->cru_register & 0x30;
99         reply |= 8;   /* IDE bus IORDY always set */
100         if (!card->clk_irq)
101            reply |= 4;
102         if (card->sram_enable_dip)
103            reply |= 2;
104         if (!card->ide_irq)
105            reply |= 1;
106      }
107      *value = reply;
108   }
109}
110
111/*
112   CRU write
113*/
114static WRITE8_DEVICE_HANDLER( cru_w )
115{
116   tn_ide_state *card = get_safe_token(device);
117
118   if ((offset & 0xff00)==CRU_BASE)
119   {
120      int bit = (offset >>1) & 7;
121      switch (bit)
122      {
123      case 0:         /* turn card on: handled by core */
124         card->selected = data;
125         
126      case 1:         /* enable SRAM or registers in 0x4000-0x40ff */
127         card->sram_enable = data;
128         break;
129         
130      case 2:         /* enable SRAM page switching */
131      case 3:         /* force SRAM page 0 */
132      case 4:         /* enable SRAM in 0x6000-0x7000 ("RAMBO" mode) */
133      case 5:         /* write-protect RAM */
134      case 6:         /* irq and reset enable */
135      case 7:         /* reset drive */
136         if (data)
137            card->cru_register |= 1 << bit;
138         else
139            card->cru_register &= ~(1 << bit);
140         
141         if (bit == 6)
142            devcb_call_write_line(&card->lines.inta, (card->cru_register & cru_reg_int_en) && card->ide_irq);
143         
144         if ((bit == 6) || (bit == 7))
145            if ((card->cru_register & cru_reg_int_en) && !(card->cru_register & cru_reg_reset))
146               card->ide->reset();
147         break;
148      }
149   }
150}
151
152/*
153    Memory read
154*/
155static READ8Z_DEVICE_HANDLER( data_rz )
156{
157   tn_ide_state *card = get_safe_token(device);
158   UINT8 reply = 0;
159
160   if (((offset & 0xe000)==0x4000) && card->selected)
161   {
162      int addr = offset & 0x1fff;
163   
164      if ((addr <= 0xff) && (card->sram_enable == card->sram_enable_dip))
165      {   /* registers */
166         switch ((addr >> 5) & 0x3)
167         {
168         case 0:      /* RTC RAM */
169            if (addr & 0x80)
170               /* RTC RAM page register */
171               reply = rtc65271_xram_r(card->rtc, (addr & 0x1f) | 0x20);
172            else
173               /* RTC RAM read */
174               reply = rtc65271_xram_r(card->rtc, addr);
175            break;
176         case 1:      /* RTC registers */
177            if (addr & 0x10)
178               /* register data */
179               reply = rtc65271_rtc_r(card->rtc, 1);
180            else
181               /* register select */
182               reply = rtc65271_rtc_r(card->rtc, 0);
183            break;
184         case 2:      /* IDE registers set 1 (CS1Fx) */
185            if (card->tms9995_mode ? (!(addr & 1)) : (addr & 1))
186            {   /* first read triggers 16-bit read cycle */
187               card->input_latch = (! (addr & 0x10)) ? ide_bus_r(card->ide, 0, (addr >> 1) & 0x7) : 0;
188            }
189           
190            /* return latched input */
191            /*reply = (addr & 1) ? input_latch : (input_latch >> 8);*/
192            /* return latched input - bytes are swapped in 2004 IDE card */
193            reply = (addr & 1) ? (card->input_latch >> 8) : card->input_latch;
194            break;
195         case 3:      /* IDE registers set 2 (CS3Fx) */
196            if (card->tms9995_mode ? (!(addr & 1)) : (addr & 1))
197            {   /* first read triggers 16-bit read cycle */
198               card->input_latch = (! (addr & 0x10)) ? ide_bus_r(card->ide, 1, (addr >> 1) & 0x7) : 0;
199            }
200           
201            /* return latched input */
202            /*reply = (addr & 1) ? input_latch : (input_latch >> 8);*/
203            /* return latched input - bytes are swapped in 2004 IDE card */
204            reply = (addr & 1) ? (card->input_latch >> 8) : card->input_latch;
205            break;
206         }
207      }
208      else
209      {   /* sram */
210         if ((card->cru_register & cru_reg_page_0) || (addr >= 0x1000))
211            reply = card->ram[addr+0x2000 * card->cur_page];
212         else
213            reply = card->ram[addr];
214      }
215      *value = reply;
216   }
217}
218
219/*
220   Memory write. The controller is 16 bit, so we need to demultiplex again.
221*/
222static WRITE8_DEVICE_HANDLER( data_w )
223{
224   tn_ide_state *card = get_safe_token(device);
225
226   if (((offset & 0xe000)==0x4000) && card->selected)
227   {
228      if (card->cru_register & cru_reg_page_switching)
229      {
230         card->cur_page = (offset >> 1) & page_mask;
231      }
232     
233      int addr = offset & 0x1fff;
234     
235      if ((addr <= 0xff) && (card->sram_enable == card->sram_enable_dip))
236      {   /* registers */
237         switch ((addr >> 5) & 0x3)
238         {
239         case 0:      /* RTC RAM */
240            if (addr & 0x80)
241               /* RTC RAM page register */
242               rtc65271_xram_w(card->rtc, (addr & 0x1f) | 0x20, data);
243            else
244               /* RTC RAM write */
245               rtc65271_xram_w(card->rtc, addr, data);
246            break;
247         case 1:      /* RTC registers */
248            if (addr & 0x10)
249               /* register data */
250               rtc65271_rtc_w(card->rtc, 1, data);
251            else
252               /* register select */
253               rtc65271_rtc_w(card->rtc, 0, data);
254            break;
255         case 2:      /* IDE registers set 1 (CS1Fx) */
256/*   
257            if (addr & 1)
258               card->output_latch = (card->output_latch & 0xff00) | data;
259            else
260               card->output_latch = (card->output_latch & 0x00ff) | (data << 8);
261*/
262            /* latch write - bytes are swapped in 2004 IDE card */
263            if (addr & 1)
264               card->output_latch = (card->output_latch & 0x00ff) | (data << 8);
265            else
266               card->output_latch = (card->output_latch & 0xff00) | data;
267           
268            if (card->tms9995_mode ? (addr & 1) : (!(addr & 1)))
269            {   /* second write triggers 16-bit write cycle */
270               ide_bus_w(card->ide, 0, (addr >> 1) & 0x7, card->output_latch);
271            }
272            break;
273         case 3:      /* IDE registers set 2 (CS3Fx) */
274/*
275            if (addr & 1)
276               card->output_latch = (card->output_latch & 0xff00) | data;
277            else
278               card->output_latch = (card->output_latch & 0x00ff) | (data << 8);
279*/
280            /* latch write - bytes are swapped in 2004 IDE card */
281            if (addr & 1)
282               card->output_latch = (card->output_latch & 0x00ff) | (data << 8);
283            else
284               card->output_latch = (card->output_latch & 0xff00) | data;
285           
286            if (card->tms9995_mode ? (addr & 1) : (!(addr & 1)))
287            {   /* second write triggers 16-bit write cycle */
288               ide_bus_w(card->ide, 1, (addr >> 1) & 0x7, card->output_latch);
289            }
290            break;
291         }
292      }
293      else
294      {   /* sram */
295         if (! (card->cru_register & cru_reg_wp))
296         {
297            if ((card->cru_register & cru_reg_page_0) || (addr >= 0x1000))
298               card->ram[addr+0x2000 * card->cur_page] = data;
299            else
300               card->ram[addr] = data;
301         }
302      }
303   }
304}
305
306/**************************************************************************/
307
308static ti99_peb_card tn_ide_card =
309{
310   data_rz, data_w,            // memory access read/write
311   cru_rz, cru_w,               // CRU access
312   NULL, NULL,                  // SENILA/B access
313   NULL, NULL                  // 16 bit access (none here)
314};
315
316/*
317    ti99_ide_interrupt()
318    IDE interrupt callback
319*/
320static void ide_interrupt_callback(running_device *device, int state)
321{
322   tn_ide_state *card = get_safe_token(device->owner());
323   card->ide_irq = state;
324   if (card->cru_register & cru_reg_int_en)
325      devcb_call_write_line(&card->lines.inta, state);
326}
327
328/*
329    clk_interrupt_callback()
330    clock interrupt callback
331*/
332static void clock_interrupt_callback(running_device *device, int state)
333{
334   tn_ide_state *card = get_safe_token(device->owner());
335   card->clk_irq = state;
336   devcb_call_write_line(&card->lines.inta, state);
337}
338
339
340static DEVICE_START( tn_ide )
341{
342   tn_ide_state *card = get_safe_token(device);
343   card->rtc = device->subdevice("ide_rtc");
344   card->ide = device->subdevice("ide");
345   
346   peb_callback_if *topeb = (peb_callback_if *)device->baseconfig().static_config();
347   devcb_resolve_write_line(&card->lines.inta, &topeb->inta, device);
348
349   card->ram = auto_alloc_array(device->machine, UINT8, 0x080000);
350   card->sram_enable_dip = 0;
351}
352
353static DEVICE_STOP( tn_ide )
354{
355}
356
357static DEVICE_RESET( tn_ide )
358{
359   tn_ide_state *card = get_safe_token(device);
360   running_device *peb = device->owner();
361   
362   if (input_port_read(device->machine, "HDCTRL") & HD_IDE)
363   {
364      int success = mount_card(peb, device, &tn_ide_card, get_pebcard_config(device)->slot);
365      if (!success) return;
366     
367      card->cur_page = 0;
368      card->sram_enable = 0;
369      card->cru_register = 0;
370      card->tms9995_mode =  (device->type()==TMS9995);
371   }
372}
373
374MACHINE_CONFIG_FRAGMENT( tn_ide )
375   MDRV_RTC65271_ADD( "ide_rtc", clock_interrupt_callback )
376   MDRV_IDE_CONTROLLER_ADD( "ide", ide_interrupt_callback )
377MACHINE_CONFIG_END
378
379static const char DEVTEMPLATE_SOURCE[] = __FILE__;
380
381#define DEVTEMPLATE_ID(p,s)             p##tn_ide##s
382#define DEVTEMPLATE_FEATURES            DT_HAS_START | DT_HAS_STOP | DT_HAS_RESET | DT_HAS_INLINE_CONFIG | DT_HAS_MACHINE_CONFIG
383#define DEVTEMPLATE_NAME                "Nouspikel IDE controller card"
384#define DEVTEMPLATE_FAMILY              "Peripheral expansion"
385#include "devtempl.h"
386
387DEFINE_LEGACY_DEVICE( TNIDE, tn_ide );
388
1/*
2    Thierry Nouspikel's IDE card emulation
3 
4    This card is just a prototype.  It has been designed by Thierry Nouspikel,
5    and its description was published in 2001.  The card have been revised in
6    2004.
7 
8    The specs have been published in <http://www.nouspikel.com/ti99/ide.html>.
9 
10    The IDE interface is quite simple, since it only implements PIO transfer.
11    The card includes a clock chip to timestamp files, and an SRAM for the DSR.
12    It should be possible to use a battery backed DSR SRAM, but since the clock
13    chip includes 4kb of battery-backed RAM, a bootstrap loader can be saved in
14    the clock SRAM in order to load the DSR from the HD when the computer
15    starts.
16 
17    Raphael Nabet, 2002-2004.
18 
19    Rewritten as device
20    Michael Zapf, September 2010
21     
22    FIXME: idecont assumes that there is only one drive that is called 
23    "harddisk" at the root level
24*/
25#include "emu.h"
26#include "peribox.h"
27#include "machine/idectrl.h"
28#include "machine/rtc65271.h"
29#include "machine/idectrl.h"
30#include "cpu/tms9900/tms9900.h"
31#include "tn_ide.h"
32 
33#define CRU_BASE 0x1000
34 
35typedef ti99_pebcard_config tn_ide_config; 
36 
37enum
38{   /* 0xff for 2 mbytes, 0x3f for 512kbytes, 0x03 for 32 kbytes */
39   page_mask = /*0xff*/0x3f
40};
41 
42enum
43{
44   cru_reg_page_switching = 0x04,
45   cru_reg_page_0 = 0x08,
46   /*cru_reg_rambo = 0x10,*/   /* not emulated */
47   cru_reg_wp = 0x20,
48   cru_reg_int_en = 0x40,
49   cru_reg_reset = 0x80
50};
51 
52typedef struct _tn_ide_state
53{
54   int    selected;
55 
56   running_device      *rtc;
57   running_device      *ide;
58 
59   int      ide_irq;
60   int      clk_irq;
61   int    sram_enable;
62   int    sram_enable_dip;
63   int    cru_register;
64   int      cur_page;
65   
66   int      tms9995_mode;
67   
68   UINT8    input_latch;
69   UINT8    output_latch;
70   
71   UINT8   *ram;
72   
73   /* Callback lines to the main system. */
74   ti99_peb_connect   lines;
75   
76} tn_ide_state;
77 
78INLINE tn_ide_state *get_safe_token(running_device *device)
79{
80   assert(device != NULL);
81   return (tn_ide_state *)downcast<legacy_device_base *>(device)->token();
82}
83 
84 
85/*
86    CRU read
87*/
88static READ8Z_DEVICE_HANDLER( cru_rz )
89{
90   tn_ide_state *card = get_safe_token(device); 
91   UINT8 reply = 0;
92   if ((offset & 0xff00)==CRU_BASE)
93   {
94      int bit = (offset >> 4) & 7;
95       
96      if (bit==0)
97      {
98         reply = card->cru_register & 0x30;
99         reply |= 8;   /* IDE bus IORDY always set */
100         if (!card->clk_irq)
101            reply |= 4;
102         if (card->sram_enable_dip)
103            reply |= 2;
104         if (!card->ide_irq)
105            reply |= 1;
106      }
107      *value = reply;
108   }
109}
110 
111/*
112   CRU write
113*/
114static WRITE8_DEVICE_HANDLER( cru_w )
115{
116   tn_ide_state *card = get_safe_token(device); 
117 
118   if ((offset & 0xff00)==CRU_BASE)
119   {
120      int bit = (offset >>1) & 7;
121      switch (bit)
122      {
123      case 0:         /* turn card on: handled by core */
124         card->selected = data;
125         
126      case 1:         /* enable SRAM or registers in 0x4000-0x40ff */
127         card->sram_enable = data;
128         break;
129         
130      case 2:         /* enable SRAM page switching */
131      case 3:         /* force SRAM page 0 */
132      case 4:         /* enable SRAM in 0x6000-0x7000 ("RAMBO" mode) */
133      case 5:         /* write-protect RAM */
134      case 6:         /* irq and reset enable */
135      case 7:         /* reset drive */
136         if (data)
137            card->cru_register |= 1 << bit;
138         else
139            card->cru_register &= ~(1 << bit);
140         
141         if (bit == 6)
142            devcb_call_write_line(&card->lines.inta, (card->cru_register & cru_reg_int_en) && card->ide_irq);
143         
144         if ((bit == 6) || (bit == 7))
145            if ((card->cru_register & cru_reg_int_en) && !(card->cru_register & cru_reg_reset))
146               card->ide->reset();
147         break;
148      }
149   }
150}
151 
152/*
153    Memory read
154*/
155static READ8Z_DEVICE_HANDLER( data_rz )
156{
157   tn_ide_state *card = get_safe_token(device); 
158   UINT8 reply = 0;
159 
160   if (((offset & 0xe000)==0x4000) && card->selected) 
161   {
162      int addr = offset & 0x1fff;
163   
164      if ((addr <= 0xff) && (card->sram_enable == card->sram_enable_dip))
165      {   /* registers */
166         switch ((addr >> 5) & 0x3)
167         {
168         case 0:      /* RTC RAM */
169            if (addr & 0x80)
170               /* RTC RAM page register */
171               reply = rtc65271_xram_r(card->rtc, (addr & 0x1f) | 0x20);
172            else
173               /* RTC RAM read */
174               reply = rtc65271_xram_r(card->rtc, addr);
175            break;
176         case 1:      /* RTC registers */
177            if (addr & 0x10)
178               /* register data */
179               reply = rtc65271_rtc_r(card->rtc, 1);
180            else
181               /* register select */
182               reply = rtc65271_rtc_r(card->rtc, 0);
183            break;
184         case 2:      /* IDE registers set 1 (CS1Fx) */
185            if (card->tms9995_mode ? (!(addr & 1)) : (addr & 1))
186            {   /* first read triggers 16-bit read cycle */
187               card->input_latch = (! (addr & 0x10)) ? ide_bus_r(card->ide, 0, (addr >> 1) & 0x7) : 0;
188            }
189             
190            /* return latched input */
191            /*reply = (addr & 1) ? input_latch : (input_latch >> 8);*/
192            /* return latched input - bytes are swapped in 2004 IDE card */
193            reply = (addr & 1) ? (card->input_latch >> 8) : card->input_latch;
194            break;
195         case 3:      /* IDE registers set 2 (CS3Fx) */
196            if (card->tms9995_mode ? (!(addr & 1)) : (addr & 1))
197            {   /* first read triggers 16-bit read cycle */
198               card->input_latch = (! (addr & 0x10)) ? ide_bus_r(card->ide, 1, (addr >> 1) & 0x7) : 0;
199            }
200             
201            /* return latched input */
202            /*reply = (addr & 1) ? input_latch : (input_latch >> 8);*/
203            /* return latched input - bytes are swapped in 2004 IDE card */
204            reply = (addr & 1) ? (card->input_latch >> 8) : card->input_latch;
205            break;
206         }
207      }
208      else
209      {   /* sram */
210         if ((card->cru_register & cru_reg_page_0) || (addr >= 0x1000))
211            reply = card->ram[addr+0x2000 * card->cur_page];
212         else
213            reply = card->ram[addr];
214      }
215      *value = reply;
216   }
217}
218 
219/*
220   Memory write. The controller is 16 bit, so we need to demultiplex again.
221*/
222static WRITE8_DEVICE_HANDLER( data_w )
223{
224   tn_ide_state *card = get_safe_token(device); 
225 
226   if (((offset & 0xe000)==0x4000) && card->selected) 
227   {
228      if (card->cru_register & cru_reg_page_switching)
229      {
230         card->cur_page = (offset >> 1) & page_mask;
231      }
232       
233      int addr = offset & 0x1fff;
234       
235      if ((addr <= 0xff) && (card->sram_enable == card->sram_enable_dip))
236      {   /* registers */
237         switch ((addr >> 5) & 0x3)
238         {
239         case 0:      /* RTC RAM */
240            if (addr & 0x80)
241               /* RTC RAM page register */
242               rtc65271_xram_w(card->rtc, (addr & 0x1f) | 0x20, data);
243            else
244               /* RTC RAM write */
245               rtc65271_xram_w(card->rtc, addr, data);
246            break;
247         case 1:      /* RTC registers */
248            if (addr & 0x10)
249               /* register data */
250               rtc65271_rtc_w(card->rtc, 1, data);
251            else
252               /* register select */
253               rtc65271_rtc_w(card->rtc, 0, data);
254            break;
255         case 2:      /* IDE registers set 1 (CS1Fx) */
256/*   
257            if (addr & 1)
258               card->output_latch = (card->output_latch & 0xff00) | data;
259            else
260               card->output_latch = (card->output_latch & 0x00ff) | (data << 8);
261*/
262            /* latch write - bytes are swapped in 2004 IDE card */
263            if (addr & 1)
264               card->output_latch = (card->output_latch & 0x00ff) | (data << 8);
265            else
266               card->output_latch = (card->output_latch & 0xff00) | data;
267             
268            if (card->tms9995_mode ? (addr & 1) : (!(addr & 1)))
269            {   /* second write triggers 16-bit write cycle */
270               ide_bus_w(card->ide, 0, (addr >> 1) & 0x7, card->output_latch);
271            }
272            break;
273         case 3:      /* IDE registers set 2 (CS3Fx) */
274/*
275            if (addr & 1)
276               card->output_latch = (card->output_latch & 0xff00) | data;
277            else
278               card->output_latch = (card->output_latch & 0x00ff) | (data << 8);
279*/
280            /* latch write - bytes are swapped in 2004 IDE card */
281            if (addr & 1)
282               card->output_latch = (card->output_latch & 0x00ff) | (data << 8);
283            else
284               card->output_latch = (card->output_latch & 0xff00) | data;
285             
286            if (card->tms9995_mode ? (addr & 1) : (!(addr & 1)))
287            {   /* second write triggers 16-bit write cycle */
288               ide_bus_w(card->ide, 1, (addr >> 1) & 0x7, card->output_latch);
289            }
290            break;
291         }
292      }
293      else
294      {   /* sram */
295         if (! (card->cru_register & cru_reg_wp))
296         {
297            if ((card->cru_register & cru_reg_page_0) || (addr >= 0x1000))
298               card->ram[addr+0x2000 * card->cur_page] = data;
299            else
300               card->ram[addr] = data;
301         }
302      }
303   }
304}
305 
306/**************************************************************************/
307 
308static ti99_peb_card tn_ide_card = 
309{
310   data_rz, data_w,            // memory access read/write
311   cru_rz, cru_w,               // CRU access
312   NULL, NULL,                  // SENILA/B access 
313   NULL, NULL                  // 16 bit access (none here)
314};
315 
316/*
317    ti99_ide_interrupt()
318    IDE interrupt callback
319*/
320static void ide_interrupt_callback(running_device *device, int state)
321{
322   tn_ide_state *card = get_safe_token(device->owner());
323   card->ide_irq = state;
324   if (card->cru_register & cru_reg_int_en)
325      devcb_call_write_line(&card->lines.inta, state);
326}
327 
328/*
329    clk_interrupt_callback()
330    clock interrupt callback
331*/
332static void clock_interrupt_callback(running_device *device, int state)
333{
334   tn_ide_state *card = get_safe_token(device->owner());
335   card->clk_irq = state;
336   devcb_call_write_line(&card->lines.inta, state);
337}
338 
339 
340static DEVICE_START( tn_ide )
341{
342   tn_ide_state *card = get_safe_token(device);
343   card->rtc = device->subdevice("ide_rtc");
344   card->ide = device->subdevice("ide");
345   
346   peb_callback_if *topeb = (peb_callback_if *)device->baseconfig().static_config();
347   devcb_resolve_write_line(&card->lines.inta, &topeb->inta, device);
348 
349   card->ram = auto_alloc_array(device->machine, UINT8, 0x080000);
350   card->sram_enable_dip = 0;
351}
352 
353static DEVICE_STOP( tn_ide )
354{
355}
356 
357static DEVICE_RESET( tn_ide )
358{
359   tn_ide_state *card = get_safe_token(device);
360   running_device *peb = device->owner();
361   
362   if (input_port_read(device->machine, "HDCTRL") & HD_IDE)
363   {
364      int success = mount_card(peb, device, &tn_ide_card, get_pebcard_config(device)->slot);
365      if (!success) return;
366       
367      card->cur_page = 0;
368      card->sram_enable = 0;
369      card->cru_register = 0;
370      card->tms9995_mode =  (device->type()==TMS9995);
371   }
372}
373 
374MACHINE_CONFIG_FRAGMENT( tn_ide )
375   MDRV_RTC65271_ADD( "ide_rtc", clock_interrupt_callback )
376   MDRV_IDE_CONTROLLER_ADD( "ide", ide_interrupt_callback )
377MACHINE_CONFIG_END
378 
379static const char DEVTEMPLATE_SOURCE[] = __FILE__;
380 
381#define DEVTEMPLATE_ID(p,s)             p##tn_ide##s
382#define DEVTEMPLATE_FEATURES            DT_HAS_START | DT_HAS_STOP | DT_HAS_RESET | DT_HAS_INLINE_CONFIG | DT_HAS_MACHINE_CONFIG
383#define DEVTEMPLATE_NAME                "Nouspikel IDE controller card"
384#define DEVTEMPLATE_FAMILY              "Peripheral expansion"
385#include "devtempl.h"
386 
387DEFINE_LEGACY_DEVICE( TNIDE, tn_ide );
388 

Previous 15994 Revisions Next


© 1998-2018 The MESS Team