Previous 15994 Revisions Next

r7147 Saturday 23rd January, 2010 at 14:45:58 UTC by Stefano Priore
Removed obsolete file
[src/mess/machine]spectrum.c

src/mess/machine/spectrum.c
r7146r7147
1/***************************************************************************
2
3  mess/machine/spectrum.c
4
5  Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
6  I/O ports)
7
8  Changes:
9
10  KT 31/1/00 - Added support for .Z80. At the moment only 48k files are supported!
11  DJR 8/2/00 - Added checks to avoid trying to load 128K .Z80 files into 48K machine!
12  DJR 20/2/00 - Added support for .TAP files.
13  -----------------27/02/00 10:54-------------------
14  KT 27/2/00 - Added my changes for the WAV support
15  --------------------------------------------------
16  DJR 14/3/00 - Fixed +3 tape loading and added option to 'rewind' tapes when end reached.
17  DJR 21/4/00 - Added support for 128K .SNA and .Z80 files.
18  DJR 21/4/00 - Ensure 48K Basic ROM is used when running 48K snapshots on 128K machine.
19  DJR 03/5/00 - Fixed bug of not decoding last byte of .Z80 blocks.
20  DJR 08/5/00 - Fixed TS2068 .TAP loading.
21  DJR 19/5/00 - .TAP files are now classified as cassette files.
22  DJR 02/6/00 - Added support for .SCR files (screendumps).
23
24***************************************************************************/
25
26#include "emu.h"
27#include "cpu/z80/z80.h"
28#include "includes/spectrum.h"
29#include "eventlst.h"
30#include "video/border.h"
31#include "devices/cassette.h"
32#include "devices/cartslot.h"
33#include "sound/ay8910.h"
34#include "utils.h"
35
36
37static void spectrum_setup_sna(running_machine *machine, unsigned char *pSnapshot, unsigned long SnapshotSize);
38static void spectrum_setup_z80(running_machine *machine, unsigned char *pSnapshot, unsigned long SnapshotSize);
39static void spectrum_setup_sp(running_machine *machine, unsigned char *pSnapshot, unsigned long SnapshotSize);
40//static int spectrum_setup_tap(offs_t address, UINT8 *snapshot_data, int snapshot_length);
41
42TIMEX_CART_TYPE timex_cart_type = TIMEX_CART_NONE;
43UINT8 timex_cart_chunks = 0x00;
44UINT8 * timex_cart_data;
45
46typedef enum
47{
48   SPECTRUM_SNAPSHOT_NONE,
49   SPECTRUM_SNAPSHOT_SNA,
50   SPECTRUM_SNAPSHOT_Z80,
51   SPECTRUM_SNAPSHOT_SP,
52   SPECTRUM_TAPEFILE_TAP
53}
54SPECTRUM_SNAPSHOT_TYPE;
55
56static DIRECT_UPDATE_HANDLER(spectrum_direct)
57{
58   /* Hack for correct handling 0xffff interrupt vector */
59   if (address == 0x0001)
60      if (cpu_get_reg(devtag_get_device(space->machine, "maincpu"), REG_GENPCBASE)==0xffff)
61      {
62         cpu_set_reg(devtag_get_device(space->machine, "maincpu"), Z80_PC, 0xfff4);
63         return 0xfff4;
64      }
65   return address;
66}
67
68MACHINE_RESET( spectrum )
69{
70   const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
71   memory_set_direct_update_handler(space, spectrum_direct);
72}
73
74SNAPSHOT_LOAD(spectrum)
75{
76   UINT8 *snapshot_data = NULL;
77
78   snapshot_data = (UINT8*)malloc(snapshot_size);
79   if (!snapshot_data)
80      goto error;
81
82   image_fread(image, snapshot_data, snapshot_size);
83
84   if (!mame_stricmp(file_type, "sna"))
85   {
86      if ((snapshot_size != 49179) && (snapshot_size != 131103) && (snapshot_size != 147487))
87      {
88         logerror("Invalid .SNA file size.\n");
89         goto error;
90      }
91      spectrum_setup_sna(image->machine, snapshot_data, snapshot_size);
92   }
93   else if (!mame_stricmp(file_type, "sp"))
94   {
95      if (snapshot_data[0]!='S' && snapshot_data[1]!='P')
96      {
97         logerror("Invalid .SP signature.\n");
98         goto error;
99      }
100      spectrum_setup_sp(image->machine, snapshot_data, snapshot_size);
101   }
102   else
103   {
104      spectrum_setup_z80(image->machine, snapshot_data, snapshot_size);
105   }
106   free(snapshot_data);
107   //logerror("Snapshot loaded - new PC = %04x\n", (unsigned) cpu_get_reg(devtag_get_device(image->machine, "maincpu"), Z80_PC) & 0x0ffff);
108   return INIT_PASS;
109
110error:
111   if (snapshot_data)
112      free(snapshot_data);
113   return INIT_FAIL;
114}
115
116/*******************************************************************
117 *
118 *      Update the memory and paging of the spectrum being emulated
119 *
120 *      if port_7ffd_data is -1 then machine is 48K - no paging
121 *      if port_1ffd_data is -1 then machine is 128K
122 *      if neither port is -1 then machine is +2a/+3
123 *
124 *      Note: the 128K .SNA and .Z80 file formats do not store the
125 *      port 1FFD setting so it is necessary to calculate the appropriate
126 *      value for the ROM paging.
127 *
128 *******************************************************************/
129static void spectrum_update_paging(running_machine *machine)
130{
131   if (spectrum_128_port_7ffd_data == -1)
132      return;
133   if (spectrum_plus3_port_1ffd_data == -1)
134      spectrum_128_update_memory(machine);
135
136   else
137   {
138      if (spectrum_128_port_7ffd_data & 0x10)
139         /* Page in Spec 48K basic ROM */
140         spectrum_plus3_port_1ffd_data = 0x04;
141      else
142         spectrum_plus3_port_1ffd_data = 0;
143      spectrum_plus3_update_memory(machine);
144   }
145}
146
147/* Page in the 48K Basic ROM. Used when running 48K snapshots on a 128K machine. */
148static void spectrum_page_basicrom(running_machine *machine)
149{
150   if (spectrum_128_port_7ffd_data == -1)
151      return;
152   spectrum_128_port_7ffd_data |= 0x10;
153   spectrum_update_paging(machine);
154}
155
156/*******************************************************************
157 *
158 *      Load a .SP file.
159 *
160 *      There are only 48K .SP files and their format is as follows:
161 *      Offset  Size    Description (all registers stored with LSB first)
162 *      0       2       "SP" (signature)
163 *      2       2       Program length in bytes (normally 49152 for 48K snaps, or 16384 for 16K snaps)
164 *      4       2       Program location (normally 16384)
165 *      6       8       BC,DE,HL,AF
166 *      14      4       IX,IY
167 *      18      8       BC',DE',HL',AF'
168 *      26      2       R,I
169 *      28      4       SP,PC
170 *      32      2       0 (reserved for future use)
171 *      34      1   Border color
172 *      35      1       0 (reserved for future use)
173 *      36      2       Status word
174 *      38      -       RAM dump
175 *
176 *  Status word:
177 *  Bit Description
178 *  15-8    Reserved for future use
179 *  7-6 Reserved for internal use (0)
180 *  5   Flash: 0=INK/1=PAPER
181 *  4   Interrupt pending for execution
182 *  3   If 1, IM 0; if 0, bit 1 determines interrupt mode
183 *          (Spectrum v 0.99e had this behaviour reversed, and this
184 *      bit was not used in versions previous to v 0.99e)
185 *  2   IFF2 (internal use)
186 *  1   Interrupt Mode (if bit 3 reset): 0=>IM1, 1=>IM2
187 *  0   IFF1: 0=DI/1=EI
188 *
189 *******************************************************************/
190void spectrum_setup_sp(running_machine *machine, unsigned char *pSnapshot, unsigned long SnapshotSize)
191{
192   int i;
193   UINT8 lo, hi, data;
194   UINT16 offset, size;
195   UINT16 status;
196   const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
197
198   lo = pSnapshot[2] & 0x0ff;
199   hi = pSnapshot[3] & 0x0ff;
200   size = (hi << 8) | lo;
201   logerror ("Snapshot data size: %d.\n", size);
202   lo = pSnapshot[4] & 0x0ff;
203   hi = pSnapshot[5] & 0x0ff;
204   offset = (hi << 8) | lo;
205   logerror ("Snapshot data offset: %d.\n", offset);
206
207   lo = pSnapshot[6] & 0x0ff;
208   hi = pSnapshot[7] & 0x0ff;
209   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_BC, (hi << 8) | lo);
210   lo = pSnapshot[8] & 0x0ff;
211   hi = pSnapshot[9] & 0x0ff;
212   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_DE, (hi << 8) | lo);
213   lo = pSnapshot[10] & 0x0ff;
214   hi = pSnapshot[11] & 0x0ff;
215   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_HL, (hi << 8) | lo);
216   lo = pSnapshot[12] & 0x0ff;
217   hi = pSnapshot[13] & 0x0ff;
218   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_AF, (hi << 8) | lo);
219
220   lo = pSnapshot[14] & 0x0ff;
221   hi = pSnapshot[15] & 0x0ff;
222   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IX, (hi << 8) | lo);
223   lo = pSnapshot[16] & 0x0ff;
224   hi = pSnapshot[17] & 0x0ff;
225   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IY, (hi << 8) | lo);
226
227   lo = pSnapshot[18] & 0x0ff;
228   hi = pSnapshot[19] & 0x0ff;
229   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_BC2, (hi << 8) | lo);
230   lo = pSnapshot[20] & 0x0ff;
231   hi = pSnapshot[21] & 0x0ff;
232   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_DE2, (hi << 8) | lo);
233   lo = pSnapshot[22] & 0x0ff;
234   hi = pSnapshot[23] & 0x0ff;
235   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_HL2, (hi << 8) | lo);
236   lo = pSnapshot[24] & 0x0ff;
237   hi = pSnapshot[25] & 0x0ff;
238   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_AF2, (hi << 8) | lo);
239
240   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_R, (pSnapshot[26] & 0x0ff));
241   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_I, (pSnapshot[27] & 0x0ff));
242
243   lo = pSnapshot[28] & 0x0ff;
244   hi = pSnapshot[29] & 0x0ff;
245   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_SP, (hi << 8) | lo);
246   lo = pSnapshot[30] & 0x0ff;
247   hi = pSnapshot[31] & 0x0ff;
248   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_PC, (hi << 8) | lo);
249
250   lo = pSnapshot[32] & 0x0ff;
251   hi = pSnapshot[33] & 0x0ff;
252   if (((hi << 8) | lo)!=0)
253      logerror("Unknown meaning of word on position 32: %04x.\n", (hi << 8) | lo);
254
255   /* Set border colour */
256   spectrum_PreviousFE = (spectrum_PreviousFE & 0xf8) | (pSnapshot[34] & 0x07);
257   EventList_Reset();
258   border_set_last_color(pSnapshot[34] & 0x07);
259   border_force_redraw();
260
261   if ((pSnapshot[35]&0x0ff)!=0)
262      logerror("Unknown meaning of byte on position 35: %02x.\n", pSnapshot[35]&0x0ff);
263
264        lo = pSnapshot[36] & 0x0ff;
265   hi = pSnapshot[37] & 0x0ff;
266   status = (hi << 8) | lo;
267
268   data = (status & 0x01);
269   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IFF1, data);
270   data = (status & 0x04) >> 2;
271   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IFF2, data);
272
273   data = (status & 0x08) >> 3;
274   if (data)
275      cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IM, 0);
276   else
277   {
278      data = (status & 0x02) >> 1;
279      if (data)
280         cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IM, 2);
281      else
282         cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IM, 1);
283   }
284
285   data = (status & 0x10) >> 4;
286   cputag_set_input_line(machine, "maincpu", 0, data);
287   cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, data);
288   cputag_set_input_line(machine, "maincpu", INPUT_LINE_HALT, 0);
289
290   spectrum_page_basicrom(machine);
291
292   /* memory dump */
293   for (i = 0; i < size; i++)
294      memory_write_byte(space, i + offset, pSnapshot[38 + i]);
295}
296
297/*******************************************************************
298 *
299 *      Load a 48K or 128K .SNA file.
300 *
301 *      48K Format as follows:
302 *      Offset  Size    Description (all registers stored with LSB first)
303 *      0       1       I
304 *      1       18      HL',DE',BC',AF',HL,DE,BC,IY,IX
305 *      19      1       Interrupt (bit 2 contains IFF2 1=EI/0=DI
306 *      20      1       R
307 *      21      4       AF,SP
308 *      25      1       Interrupt Mode (0=IM0/1=IM1/2=IM2)
309 *      26      1       Border Colour (0..7)
310 *      27      48K     RAM dump 0x4000-0xffff
311 *      PC is stored on stack.
312 *
313 *      128K Format as follows:
314 *      Offset  Size    Description
315 *      0       27      Header as 48K
316 *      27      16K     RAM bank 5 (0x4000-0x7fff)
317 *      16411   16K     RAM bank 2 (0x8000-0xbfff)
318 *      32795   16K     RAM bank n (0xc000-0xffff - currently paged bank)
319 *      49179   2       PC
320 *      49181   1       port 7FFD setting
321 *      49182   1       TR-DOS rom paged (1=yes)
322 *      49183   16K     remaining RAM banks in ascending order
323 *
324 *      The bank in 0xc000 is always included even if it is page 2 or 5
325 *      in which case it is included twice.
326 *
327 *******************************************************************/
328void spectrum_setup_sna(running_machine *machine, unsigned char *pSnapshot, unsigned long SnapshotSize)
329{
330   int i, j, usedbanks[8];
331   long bank_offset;
332   unsigned char lo, hi, data;
333   unsigned short addr;
334   const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
335
336   if ((SnapshotSize != 49179) && (spectrum_128_port_7ffd_data == -1))
337   {
338      logerror("Can't load 128K .SNA file into 48K machine\n");
339      return;
340   }
341
342   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_I, (pSnapshot[0] & 0x0ff));
343   lo = pSnapshot[1] & 0x0ff;
344   hi = pSnapshot[2] & 0x0ff;
345   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_HL2, (hi << 8) | lo);
346   lo = pSnapshot[3] & 0x0ff;
347   hi = pSnapshot[4] & 0x0ff;
348   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_DE2, (hi << 8) | lo);
349   lo = pSnapshot[5] & 0x0ff;
350   hi = pSnapshot[6] & 0x0ff;
351   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_BC2, (hi << 8) | lo);
352   lo = pSnapshot[7] & 0x0ff;
353   hi = pSnapshot[8] & 0x0ff;
354   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_AF2, (hi << 8) | lo);
355   lo = pSnapshot[9] & 0x0ff;
356   hi = pSnapshot[10] & 0x0ff;
357   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_HL, (hi << 8) | lo);
358   lo = pSnapshot[11] & 0x0ff;
359   hi = pSnapshot[12] & 0x0ff;
360   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_DE, (hi << 8) | lo);
361   lo = pSnapshot[13] & 0x0ff;
362   hi = pSnapshot[14] & 0x0ff;
363   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_BC, (hi << 8) | lo);
364   lo = pSnapshot[15] & 0x0ff;
365   hi = pSnapshot[16] & 0x0ff;
366   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IY, (hi << 8) | lo);
367   lo = pSnapshot[17] & 0x0ff;
368   hi = pSnapshot[18] & 0x0ff;
369   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IX, (hi << 8) | lo);
370   data = (pSnapshot[19] & 0x04) >> 2;
371   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IFF2, data);
372   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IFF1, data);
373   data = (pSnapshot[20] & 0x0ff);
374   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_R, data);
375   lo = pSnapshot[21] & 0x0ff;
376   hi = pSnapshot[22] & 0x0ff;
377   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_AF, (hi << 8) | lo);
378   lo = pSnapshot[23] & 0x0ff;
379   hi = pSnapshot[24] & 0x0ff;
380   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_SP, (hi << 8) | lo);
381   data = (pSnapshot[25] & 0x0ff);
382   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IM, data);
383
384   /* Set border colour */
385   spectrum_PreviousFE = (spectrum_PreviousFE & 0xf8) | (pSnapshot[26] & 0x07);
386   EventList_Reset();
387   border_set_last_color(pSnapshot[26] & 0x07);
388   border_force_redraw();
389
390   cputag_set_input_line(machine, "maincpu", 0, data);
391   cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, data);
392   cputag_set_input_line(machine, "maincpu", INPUT_LINE_HALT, 0);
393
394   if (SnapshotSize == 49179)
395      /* 48K Snapshot */
396      spectrum_page_basicrom(machine);
397   else
398   {
399      /* 128K Snapshot */
400      spectrum_128_port_7ffd_data = (pSnapshot[49181] & 0x0ff);
401      spectrum_update_paging(machine);
402   }
403
404   /* memory dump */
405   for (i = 0; i < 49152; i++)
406   {
407      memory_write_byte(space,i + 16384, pSnapshot[27 + i]);
408   }
409
410   if (SnapshotSize == 49179)
411   {
412      /* get pc from stack */
413      addr = cpu_get_reg(devtag_get_device(machine, "maincpu"), Z80_SP) & 0xFFFF;
414
415      lo = memory_read_byte(space,addr + 0);
416      hi = memory_read_byte(space,addr + 1);
417      cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_PC, (hi << 8) | lo);
418      memory_write_byte(space, addr + 0, 0);
419      memory_write_byte(space, addr + 1, 0);
420
421      memory_write_byte(space, 0x5CB0, 0xff); // Set NMIADD system variable to make game run
422                                    //  when directly started with cart mounted
423      addr += 2;
424      cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_SP, (addr & 0x0ffff));
425   }
426   else
427   {
428      /* Set up other RAM banks */
429      bank_offset = 49183;
430      for (i = 0; i < 8; i++)
431         usedbanks[i] = 0;
432
433      usedbanks[5] = 1;            /* 0x4000-0x7fff */
434      usedbanks[2] = 1;            /* 0x8000-0xbfff */
435      usedbanks[spectrum_128_port_7ffd_data & 0x07] = 1;   /* Banked memory */
436
437      for (i = 0; i < 8; i++)
438      {
439         if (!usedbanks[i])
440         {
441            logerror("Loading bank %d from offset %ld\n", i, bank_offset);
442            spectrum_128_port_7ffd_data &= 0xf8;
443            spectrum_128_port_7ffd_data += i;
444            spectrum_update_paging(machine);
445            for (j = 0; j < 16384; j++)
446               memory_write_byte(space,j + 49152, pSnapshot[bank_offset + j]);
447            bank_offset += 16384;
448         }
449      }
450
451      /* Reset paging */
452      spectrum_128_port_7ffd_data = (pSnapshot[49181] & 0x0ff);
453      spectrum_update_paging(machine);
454
455      /* program counter */
456      lo = pSnapshot[49179] & 0x0ff;
457      hi = pSnapshot[49180] & 0x0ff;
458      cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_PC, (hi << 8) | lo);
459   }
460}
461
462
463static void spectrum_z80_decompress_block(running_machine *machine,unsigned char *pSource, int Dest, int size)
464{
465   unsigned char ch;
466   int i;
467   const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
468
469   do
470   {
471      /* get byte */
472      ch = pSource[0];
473
474      /* either start 0f 0x0ed, 0x0ed, xx yy or
475         * single 0x0ed */
476      if (ch == (unsigned char) 0x0ed)
477      {
478         if (pSource[1] == (unsigned char) 0x0ed)
479         {
480
481            /* 0x0ed, 0x0ed, xx yy */
482            /* repetition */
483
484            int count;
485            int data;
486
487            count = (pSource[2] & 0x0ff);
488
489            if (count == 0)
490               return;
491
492            data = (pSource[3] & 0x0ff);
493
494            pSource += 4;
495
496            if (count > size)
497               count = size;
498
499            size -= count;
500
501            for (i = 0; i < count; i++)
502            {
503               memory_write_byte(space,Dest, data);
504               Dest++;
505            }
506         }
507         else
508         {
509            /* single 0x0ed */
510            memory_write_byte(space,Dest, ch);
511            Dest++;
512            pSource++;
513            size--;
514
515         }
516      }
517      else
518      {
519         /* not 0x0ed */
520         memory_write_byte(space,Dest, ch);
521         Dest++;
522         pSource++;
523         size--;
524      }
525
526   }
527   while (size > 0);
528}
529
530typedef enum {
531   SPECTRUM_Z80_SNAPSHOT_INVALID,
532   SPECTRUM_Z80_SNAPSHOT_48K_OLD,
533   SPECTRUM_Z80_SNAPSHOT_48K,
534   SPECTRUM_Z80_SNAPSHOT_SAMRAM,
535   SPECTRUM_Z80_SNAPSHOT_128K,
536   SPECTRUM_Z80_SNAPSHOT_TS2068
537}
538SPECTRUM_Z80_SNAPSHOT_TYPE;
539
540static SPECTRUM_Z80_SNAPSHOT_TYPE spectrum_identify_z80 (unsigned char *pSnapshot, unsigned long SnapshotSize)
541{
542   unsigned char lo, hi, data;
543
544   if (SnapshotSize < 30)
545      return SPECTRUM_Z80_SNAPSHOT_INVALID;   /* Invalid file */
546
547   lo = pSnapshot[6] & 0x0ff;
548   hi = pSnapshot[7] & 0x0ff;
549   if (hi || lo)
550      return SPECTRUM_Z80_SNAPSHOT_48K_OLD;   /* V1.45 - 48K only */
551
552   lo = pSnapshot[30] & 0x0ff;
553   hi = pSnapshot[31] & 0x0ff;
554   data = pSnapshot[34] & 0x0ff;         /* Hardware mode */
555
556   if ((hi == 0) && (lo == 23))
557   {                  /* V2.01 */                     /* V2.01 format */
558      switch (data)
559      {
560         case 0:
561         case 1:   return SPECTRUM_Z80_SNAPSHOT_48K;
562         case 2:   return SPECTRUM_Z80_SNAPSHOT_SAMRAM;
563         case 3:
564         case 4:   return SPECTRUM_Z80_SNAPSHOT_128K;
565         case 128: return SPECTRUM_Z80_SNAPSHOT_TS2068;
566      }
567   }
568
569   if ((hi == 0) && (lo == 54))
570   {                  /* V3.0x */                     /* V2.01 format */
571      switch (data)
572      {
573         case 0:
574         case 1:
575         case 3:   return SPECTRUM_Z80_SNAPSHOT_48K;
576         case 2:   return SPECTRUM_Z80_SNAPSHOT_SAMRAM;
577         case 4:
578         case 5:
579         case 6:   return SPECTRUM_Z80_SNAPSHOT_128K;
580         case 128: return SPECTRUM_Z80_SNAPSHOT_TS2068;
581      }
582   }
583
584   return SPECTRUM_Z80_SNAPSHOT_INVALID;
585}
586
587/* now supports 48k & 128k .Z80 files */
588void spectrum_setup_z80(running_machine *machine, unsigned char *pSnapshot, unsigned long SnapshotSize)
589{
590   int i;
591   unsigned char lo, hi, data;
592   SPECTRUM_Z80_SNAPSHOT_TYPE z80_type;
593   const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
594
595   z80_type = spectrum_identify_z80(pSnapshot, SnapshotSize);
596
597   switch (z80_type)
598   {
599      case SPECTRUM_Z80_SNAPSHOT_INVALID:
600            logerror("Invalid .Z80 file\n");
601            return;
602      case SPECTRUM_Z80_SNAPSHOT_48K_OLD:
603      case SPECTRUM_Z80_SNAPSHOT_48K:
604            logerror("48K .Z80 file\n");
605            if (!strcmp(machine->gamedrv->name,"ts2068"))
606               logerror("48K .Z80 file in TS2068\n");
607            break;
608      case SPECTRUM_Z80_SNAPSHOT_128K:
609            logerror("128K .Z80 file\n");
610            if (spectrum_128_port_7ffd_data == -1)
611            {
612               logerror("Not a 48K .Z80 file\n");
613               return;
614            }
615            if (!strcmp(machine->gamedrv->name,"ts2068"))
616            {
617               logerror("Not a TS2068 .Z80 file\n");
618               return;
619            }
620            break;
621      case SPECTRUM_Z80_SNAPSHOT_TS2068:
622            logerror("TS2068 .Z80 file\n");
623            if (strcmp(machine->gamedrv->name,"ts2068"))
624               logerror("Not a TS2068 machine\n");
625            break;
626      case SPECTRUM_Z80_SNAPSHOT_SAMRAM:
627            logerror("Hardware not supported - .Z80 file\n");
628            return;
629   }
630
631   /* AF */
632   hi = pSnapshot[0] & 0x0ff;
633   lo = pSnapshot[1] & 0x0ff;
634   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_AF, (hi << 8) | lo);
635   /* BC */
636   lo = pSnapshot[2] & 0x0ff;
637   hi = pSnapshot[3] & 0x0ff;
638   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_BC, (hi << 8) | lo);
639   /* HL */
640   lo = pSnapshot[4] & 0x0ff;
641   hi = pSnapshot[5] & 0x0ff;
642   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_HL, (hi << 8) | lo);
643
644   /* SP */
645   lo = pSnapshot[8] & 0x0ff;
646   hi = pSnapshot[9] & 0x0ff;
647   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_SP, (hi << 8) | lo);
648
649   /* I */
650   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_I, (pSnapshot[10] & 0x0ff));
651
652   /* R */
653   data = (pSnapshot[11] & 0x07f) | ((pSnapshot[12] & 0x01) << 7);
654   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_R, data);
655
656   /* Set border colour */
657   spectrum_PreviousFE = (spectrum_PreviousFE & 0xf8) | ((pSnapshot[12] & 0x0e) >> 1);
658   EventList_Reset();
659   border_set_last_color((pSnapshot[12] & 0x0e) >> 1);
660   border_force_redraw();
661
662   lo = pSnapshot[13] & 0x0ff;
663   hi = pSnapshot[14] & 0x0ff;
664   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_DE, (hi << 8) | lo);
665
666   lo = pSnapshot[15] & 0x0ff;
667   hi = pSnapshot[16] & 0x0ff;
668   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_BC2, (hi << 8) | lo);
669
670   lo = pSnapshot[17] & 0x0ff;
671   hi = pSnapshot[18] & 0x0ff;
672   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_DE2, (hi << 8) | lo);
673
674   lo = pSnapshot[19] & 0x0ff;
675   hi = pSnapshot[20] & 0x0ff;
676   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_HL2, (hi << 8) | lo);
677
678   hi = pSnapshot[21] & 0x0ff;
679   lo = pSnapshot[22] & 0x0ff;
680   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_AF2, (hi << 8) | lo);
681
682   lo = pSnapshot[23] & 0x0ff;
683   hi = pSnapshot[24] & 0x0ff;
684   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IY, (hi << 8) | lo);
685
686   lo = pSnapshot[25] & 0x0ff;
687   hi = pSnapshot[26] & 0x0ff;
688   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IX, (hi << 8) | lo);
689
690   /* Interrupt Flip/Flop */
691   if (pSnapshot[27] == 0)
692   {
693      cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IFF1, 0);
694      /* cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IRQ_STATE, 0); */
695   }
696   else
697   {
698      cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IFF1, 1);
699      /* cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IRQ_STATE, 1); */
700   }
701
702   cputag_set_input_line(machine, "maincpu", 0, data);
703   cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, data);
704   cputag_set_input_line(machine, "maincpu", INPUT_LINE_HALT, 0);
705
706   /* IFF2 */
707   if (pSnapshot[28] != 0)
708   {
709      data = 1;
710   }
711   else
712   {
713      data = 0;
714   }
715   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IFF2, data);
716
717   /* Interrupt Mode */
718   cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_IM, (pSnapshot[29] & 0x03));
719
720   if (z80_type == SPECTRUM_Z80_SNAPSHOT_48K_OLD)
721   {
722      lo = pSnapshot[6] & 0x0ff;
723      hi = pSnapshot[7] & 0x0ff;
724      cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_PC, (hi << 8) | lo);
725
726      spectrum_page_basicrom(machine);
727
728      if ((pSnapshot[12] & 0x020) == 0)
729      {
730         logerror("Not compressed\n");   /* not compressed */
731         for (i = 0; i < 49152; i++)
732            memory_write_byte(space,i + 16384, pSnapshot[30 + i]);
733      }
734      else
735      {
736         logerror("Compressed\n");   /* compressed */
737         spectrum_z80_decompress_block(machine, pSnapshot + 30, 16384, 49152);
738      }
739   }
740   else
741   {
742      unsigned char *pSource;
743      int header_size;
744
745      header_size = 30 + 2 + ((pSnapshot[30] & 0x0ff) | ((pSnapshot[31] & 0x0ff) << 8));
746
747      lo = pSnapshot[32] & 0x0ff;
748      hi = pSnapshot[33] & 0x0ff;
749      cpu_set_reg(devtag_get_device(machine, "maincpu"), Z80_PC, (hi << 8) | lo);
750
751      if ((z80_type == SPECTRUM_Z80_SNAPSHOT_128K) || ((z80_type == SPECTRUM_Z80_SNAPSHOT_TS2068) && !strcmp(machine->gamedrv->name,"ts2068")))
752      {
753         const device_config *ay8912 = devtag_get_device(machine, "ay8912");
754
755         /* Only set up sound registers for 128K machine or TS2068! */
756         for (i = 0; i < 16; i++)
757         {
758            ay8910_address_w(ay8912, 0, i);
759            ay8910_data_w(ay8912, 0, pSnapshot[39 + i]);
760         }
761         ay8910_address_w(ay8912, 0, pSnapshot[38]);
762      }
763
764      pSource = pSnapshot + header_size;
765
766      if (z80_type == SPECTRUM_Z80_SNAPSHOT_48K)
767         /* Ensure 48K Basic ROM is used */
768         spectrum_page_basicrom(machine);
769
770      do
771      {
772         unsigned short length;
773         unsigned char page;
774         int Dest = 0;
775
776         length = (pSource[0] & 0x0ff) | ((pSource[1] & 0x0ff) << 8);
777         page = pSource[2];
778
779         if (z80_type == SPECTRUM_Z80_SNAPSHOT_48K || z80_type == SPECTRUM_Z80_SNAPSHOT_TS2068)
780         {
781            switch (page)
782            {
783               case 4:   Dest = 0x08000;   break;
784               case 5:   Dest = 0x0c000;   break;
785               case 8:   Dest = 0x04000;   break;
786               default: Dest = 0; break;
787            }
788         }
789         else
790         {
791            /* 3 = bank 0, 4 = bank 1 ... 10 = bank 7 */
792            if ((page >= 3) && (page <= 10))
793            {
794               /* Page the appropriate bank into 0xc000 - 0xfff */
795               spectrum_128_port_7ffd_data = page - 3;
796               spectrum_update_paging(machine);
797               Dest = 0x0c000;
798            }
799            else
800               /* Other values correspond to ROM pages */
801               Dest = 0x0;
802         }
803
804         if (Dest != 0)
805         {
806            if (length == 0x0ffff)
807            {
808               /* block is uncompressed */
809               logerror("Not compressed\n");
810
811               /* not compressed */
812               for (i = 0; i < 16384; i++)
813                  memory_write_byte(space,i + Dest, pSource[i]);
814            }
815            else
816            {
817               logerror("Compressed\n");
818
819               /* block is compressed */
820               spectrum_z80_decompress_block(machine,&pSource[3], Dest, 16384);
821            }
822         }
823
824         /* go to next block */
825         pSource += (3 + length);
826      }
827      while ((pSource - pSnapshot) < SnapshotSize);
828
829      if ((spectrum_128_port_7ffd_data != -1) && (z80_type != SPECTRUM_Z80_SNAPSHOT_48K))
830      {
831         /* Set up paging */
832         spectrum_128_port_7ffd_data = (pSnapshot[35] & 0x0ff);
833         spectrum_update_paging(machine);
834      }
835      if ((z80_type == SPECTRUM_Z80_SNAPSHOT_48K) && !strcmp(machine->gamedrv->name,"ts2068"))
836      {
837         ts2068_port_f4_data = 0x03;
838         ts2068_port_ff_data = 0x00;
839         ts2068_update_memory(machine);
840      }
841      if (z80_type == SPECTRUM_Z80_SNAPSHOT_TS2068 && !strcmp(machine->gamedrv->name,"ts2068"))
842      {
843         ts2068_port_f4_data = pSnapshot[35];
844         ts2068_port_ff_data = pSnapshot[36];
845         ts2068_update_memory(machine);
846      }
847   }
848}
849
850/*-----------------27/02/00 10:54-------------------
851 SPECTRUM WAVE CASSETTE SUPPORT
852--------------------------------------------------*/
853
854/*************************************
855 *
856 *      Interrupt handlers.
857 *
858 *************************************/
859
860QUICKLOAD_LOAD(spectrum)
861{
862   const address_space *space = cputag_get_address_space(image->machine, "maincpu", ADDRESS_SPACE_PROGRAM);
863   int i;
864   int quick_addr = 0x4000;
865   int quick_length;
866   UINT8 *quick_data;
867   int read_;
868
869   quick_length = image_length(image);
870   quick_data = (UINT8 *)malloc(quick_length);
871   if (!quick_data)
872      return INIT_FAIL;
873
874   read_ = image_fread(image, quick_data, quick_length);
875   if (read_ != quick_length)
876      return INIT_FAIL;
877
878   for (i = 0; i < quick_length; i++)
879      memory_write_byte(space,i + quick_addr, quick_data[i]);
880
881   logerror("quick loading at %.4x size:%.4x\n", quick_addr, quick_length);
882   return INIT_PASS;
883}
884
885DEVICE_IMAGE_LOAD( timex_cart )
886{
887   int file_size;
888   UINT8 * file_data;
889
890   int chunks_in_file = 0;
891
892   int i;
893
894   logerror ("Trying to load cart\n");
895
896   file_size = image_length(image);
897
898   if (file_size < 0x09)
899   {
900      logerror ("Bad file size\n");
901      return INIT_FAIL;
902   }
903
904   file_data = (UINT8 *)malloc(file_size);
905   if (file_data == NULL)
906   {
907      logerror ("Memory allocating error\n");
908      return INIT_FAIL;
909   }
910
911   image_fread(image, file_data, file_size);
912
913   for (i=0; i<8; i++)
914      if(file_data[i+1]&0x02)   chunks_in_file++;
915
916   if (chunks_in_file*0x2000+0x09 != file_size)
917   {
918      free (file_data);
919      logerror ("File corrupted\n");
920      return INIT_FAIL;
921   }
922
923   switch (file_data[0x00])
924   {
925      case 0x00:   logerror ("DOCK cart\n");
926            timex_cart_type = TIMEX_CART_DOCK;
927            timex_cart_data = (UINT8*) malloc (0x10000);
928            if (!timex_cart_data)
929            {
930               free (file_data);
931               logerror ("Memory allocate error\n");
932               return INIT_FAIL;
933            }
934            chunks_in_file = 0;
935            for (i=0; i<8; i++)
936            {
937               timex_cart_chunks = timex_cart_chunks | ((file_data[i+1]&0x01)<<i);
938               if (file_data[i+1]&0x02)
939               {
940                  memcpy (timex_cart_data+i*0x2000, file_data+0x09+chunks_in_file*0x2000, 0x2000);
941                  chunks_in_file++;
942               }
943               else
944               {
945                  if (file_data[i+1]&0x01)
946                     memset (timex_cart_data+i*0x2000, 0x00, 0x2000);
947                  else
948                     memset (timex_cart_data+i*0x2000, 0xff, 0x2000);
949               }
950            }
951            free (file_data);
952            break;
953
954      default:   logerror ("Cart type not supported\n");
955            free (file_data);
956            timex_cart_type = TIMEX_CART_NONE;
957            return INIT_FAIL;
958   }
959
960   logerror ("Cart loaded\n");
961   logerror ("Chunks %02x\n", timex_cart_chunks);
962   return INIT_PASS;
963}
964
965DEVICE_IMAGE_UNLOAD( timex_cart )
966{
967   if (timex_cart_data)
968   {
969      free (timex_cart_data);
970      timex_cart_data = NULL;
971   }
972   timex_cart_type = TIMEX_CART_NONE;
973   timex_cart_chunks = 0x00;
974}

Previous 15994 Revisions Next


© 1998-2018 The MESS Team