Previous 199869 Revisions Next

r21310 Friday 22nd February, 2013 at 11:49:43 UTC by Miodrag Milanović
Finished moving quicload/snapshot formats into machine folder (nw)
[src/mess]formats mess.mak messcore.mak
[src/mess/drivers]c128.c c64.c c65.c cbm2.c mbee.c pet2001.c plus4.c sorcerer.c spectrum.c super80.c timex.c vic20.c
[src/mess/includes]c128.h c64.h cbm2.h mbee.h pet2001.h plus4.h sorcerer.h super80.h vic20.h
[src/mess/machine]c64exp.h cbm_crt.c* cbm_crt.h* cbm_snqk.c* cbm_snqk.h* mbee.c sorcerer.c spec_snqk.c* spec_snqk.h* super80.c vic10exp.c vic10exp.h vic20exp.c z80bin.c* z80bin.h*

trunk/src/mess/drivers/c64.c
r21309r21310
2828#define VA13 BIT(va, 13)
2929#define VA12 BIT(va, 12)
3030
31static QUICKLOAD_LOAD( cbm_c64 )
32{
33   return general_cbm_loadsnap(image, file_type, quickload_size, 0, cbm_quick_sethiaddress);
34}
3135
3236
3337//**************************************************************************
trunk/src/mess/drivers/c65.c
r21309r21310
5757#include "machine/cbmipt.h"
5858#include "video/vic4567.h"
5959#include "includes/cbm.h"
60#include "formats/cbm_snqk.h"
60#include "machine/cbm_snqk.h"
6161#include "includes/c64_legacy.h"
6262#include "includes/c65.h"
6363#include "machine/cbmiec.h"
6464#include "machine/ram.h"
6565
66static void cbm_c65_quick_sethiaddress( running_machine &machine, UINT16 hiaddress )
67{
68   address_space &space = machine.firstcpu->space(AS_PROGRAM);
69
70   space.write_byte(0x82, hiaddress & 0xff);
71   space.write_byte(0x83, hiaddress >> 8);
72}
73
74static QUICKLOAD_LOAD( cbm_c65 )
75{
76   return general_cbm_loadsnap(image, file_type, quickload_size, 0, cbm_c65_quick_sethiaddress);
77}
78
6679/*************************************
6780 *
6881 *  Main CPU memory handlers
trunk/src/mess/drivers/pet2001.c
r21309r21310
152152
153153#include "includes/pet2001.h"
154154
155static void cbm_pet_quick_sethiaddress( running_machine &machine, UINT16 hiaddress )
156{
157   address_space &space = machine.firstcpu->space(AS_PROGRAM);
155158
159   space.write_byte(0x2e, hiaddress & 0xff);
160   space.write_byte(0x2c, hiaddress & 0xff);
161   space.write_byte(0x2a, hiaddress & 0xff);
162   space.write_byte(0x2f, hiaddress >> 8);
163   space.write_byte(0x2d, hiaddress >> 8);
164   space.write_byte(0x2b, hiaddress >> 8);
165}
156166
167static QUICKLOAD_LOAD( cbm_pet )
168{
169   return general_cbm_loadsnap(image, file_type, quickload_size, 0, cbm_pet_quick_sethiaddress);
170}
171
157172//**************************************************************************
158173//  INTERRUPTS
159174//**************************************************************************
trunk/src/mess/drivers/c128.c
r21309r21310
2828
2929
3030
31static QUICKLOAD_LOAD( cbm_c64 )
32{
33   return general_cbm_loadsnap(image, file_type, quickload_size, 0, cbm_quick_sethiaddress);
34}
35
3136//**************************************************************************
3237//  INTERRUPTS
3338//**************************************************************************
trunk/src/mess/drivers/vic20.c
r21309r21310
1111
1212
1313
14static QUICKLOAD_LOAD( cbm_vc20 )
15{
16   return general_cbm_loadsnap(image, file_type, quickload_size, 0, cbm_quick_sethiaddress);
17}
18
1419//**************************************************************************
1520//  MEMORY MANAGEMENT
1621//**************************************************************************
trunk/src/mess/drivers/plus4.c
r21309r21310
3333
3434
3535
36static QUICKLOAD_LOAD( cbm_c16 )
37{
38   return general_cbm_loadsnap(image, file_type, quickload_size, 0, cbm_quick_sethiaddress);
39}
40
3641//**************************************************************************
3742//  INTERRUPTS
3843//**************************************************************************
trunk/src/mess/drivers/spectrum.c
r21309r21310
278278#include "sound/wave.h"
279279#include "includes/spectrum.h"
280280#include "formats/tzx_cas.h"
281#include "formats/spec_snqk.h"
281#include "machine/spec_snqk.h"
282282
283283
284284/****************************************************************************************************/
trunk/src/mess/drivers/sorcerer.c
r21309r21310
156156********************************************************************************/
157157
158158#include "includes/sorcerer.h"
159#include "formats/z80bin.h"
160159
161160static ADDRESS_MAP_START( sorcerer_mem, AS_PROGRAM, 8, sorcerer_state)
162161   ADDRESS_MAP_UNMAP_HIGH
trunk/src/mess/drivers/timex.c
r21309r21310
153153#include "sound/speaker.h"
154154#include "sound/ay8910.h"
155155#include "formats/tzx_cas.h"
156#include "formats/spec_snqk.h"
157#include "formats/timex_dck.h"
156#include "machine/spec_snqk.h"
158157#include "machine/beta.h"
159158#include "machine/ram.h"
160159
160enum
161{
162   TIMEX_CART_NONE,
163   TIMEX_CART_DOCK,
164   TIMEX_CART_EXROM,
165   TIMEX_CART_HOME
166};
167
168struct timex_cart_t
169{
170   int type;
171   UINT8 chunks;
172   UINT8 *data;
173};
174
175static timex_cart_t timex_cart;
176
177
178DEVICE_IMAGE_LOAD_LEGACY( timex_cart )
179{
180   int file_size;
181   UINT8 * file_data;
182
183   int chunks_in_file = 0;
184
185   int i;
186
187   logerror ("Trying to load cart\n");
188
189   file_size = image.length();
190
191   if (file_size < 0x09)
192   {
193      logerror ("Bad file size\n");
194      return IMAGE_INIT_FAIL;
195   }
196
197   file_data = (UINT8 *)malloc(file_size);
198   if (file_data == NULL)
199   {
200      logerror ("Memory allocating error\n");
201      return IMAGE_INIT_FAIL;
202   }
203
204   image.fread(file_data, file_size);
205
206   for (i=0; i<8; i++)
207      if(file_data[i+1]&0x02) chunks_in_file++;
208
209   if (chunks_in_file*0x2000+0x09 != file_size)
210   {
211      free (file_data);
212      logerror ("File corrupted\n");
213      return IMAGE_INIT_FAIL;
214   }
215
216   switch (file_data[0x00])
217   {
218      case 0x00:  logerror ("DOCK cart\n");
219            timex_cart.type = TIMEX_CART_DOCK;
220            timex_cart.data = (UINT8*) malloc (0x10000);
221            if (!timex_cart.data)
222            {
223               free (file_data);
224               logerror ("Memory allocate error\n");
225               return IMAGE_INIT_FAIL;
226            }
227            chunks_in_file = 0;
228            for (i=0; i<8; i++)
229            {
230               timex_cart.chunks = timex_cart.chunks | ((file_data[i+1]&0x01)<<i);
231               if (file_data[i+1]&0x02)
232               {
233                  memcpy (timex_cart.data+i*0x2000, file_data+0x09+chunks_in_file*0x2000, 0x2000);
234                  chunks_in_file++;
235               }
236               else
237               {
238                  if (file_data[i+1]&0x01)
239                     memset (timex_cart.data+i*0x2000, 0x00, 0x2000);
240                  else
241                     memset (timex_cart.data+i*0x2000, 0xff, 0x2000);
242               }
243            }
244            free (file_data);
245            break;
246
247      default:    logerror ("Cart type not supported\n");
248            free (file_data);
249            timex_cart.type = TIMEX_CART_NONE;
250            return IMAGE_INIT_FAIL;
251   }
252
253   logerror ("Cart loaded\n");
254   logerror ("Chunks %02x\n", timex_cart.chunks);
255   return IMAGE_INIT_PASS;
256}
257
258DEVICE_IMAGE_UNLOAD_LEGACY( timex_cart )
259{
260   if (timex_cart.data)
261   {
262      free (timex_cart.data);
263      timex_cart.data = NULL;
264   }
265   timex_cart.type = TIMEX_CART_NONE;
266   timex_cart.chunks = 0x00;
267}
268
269const timex_cart_t *timex_cart_data(void)
270{
271   return &timex_cart;
272}
273
161274static const ay8910_interface spectrum_ay_interface =
162275{
163276   AY8910_LEGACY_OUTPUT,
trunk/src/mess/drivers/cbm2.c
r21309r21310
2929#define A0 BIT(offset, 0)
3030#define VA12 BIT(va, 12)
3131
32static void cbmb_quick_sethiaddress(running_machine &machine, UINT16 hiaddress)
33{
34   address_space &space = machine.firstcpu->space(AS_PROGRAM);
3235
36   space.write_byte(0xf0046, hiaddress & 0xff);
37   space.write_byte(0xf0047, hiaddress >> 8);
38}
3339
40static QUICKLOAD_LOAD( cbmb )
41{
42   return general_cbm_loadsnap(image, file_type, quickload_size, 0x10000, cbmb_quick_sethiaddress);
43}
44
45static QUICKLOAD_LOAD( p500 )
46{
47   return general_cbm_loadsnap(image, file_type, quickload_size, 0, cbmb_quick_sethiaddress);
48}
49
3450//**************************************************************************
3551//  ADDRESS DECODING
3652//**************************************************************************
trunk/src/mess/drivers/super80.c
r21309r21310
183183
184184#include "super80.lh"
185185#include "includes/super80.h"
186#include "formats/z80bin.h"
187186
188187#define MASTER_CLOCK    (XTAL_12MHz)
189188#define PIXEL_CLOCK (MASTER_CLOCK/2)
trunk/src/mess/drivers/mbee.c
r21309r21310
9191
9292#include "emu.h"
9393#include "includes/mbee.h"
94#include "formats/z80bin.h"
9594
9695#define XTAL_13_5MHz 13500000
9796
trunk/src/mess/mess.mak
r21309r21310
555555   $(MESS_MACHINE)/ne1000.o    \
556556   $(MESS_MACHINE)/ne2000.o    \
557557   $(MESS_MACHINE)/3c503.o     \
558   $(MESS_FORMATS)/z80bin.o    \
558   $(MESS_MACHINE)/z80bin.o    \
559559   $(MESS_MACHINE)/mb8795.o    \
560560   $(MESS_MACHINE)/midiinport.o    \
561561   $(MESS_MACHINE)/midioutport.o   \
r21309r21310
958958   $(MESS_VIDEO)/vic4567.o     \
959959   $(MESS_VIDEO)/mos6566.o     \
960960   $(MESS_DRIVERS)/c900.o      \
961   $(MESS_FORMATS)/cbm_snqk.o  \
962   $(MESS_FORMATS)/cbm_crt.o   \
961   $(MESS_MACHINE)/cbm_snqk.o  \
962   $(MESS_MACHINE)/cbm_crt.o   \
963963
964964$(MESSOBJ)/cccp.a:              \
965965   $(MESS_DRIVERS)/argo.o      \
r21309r21310
17051705   $(MESS_DRIVERS)/atm.o       \
17061706   $(MESS_DRIVERS)/pentagon.o  \
17071707   $(MESS_MACHINE)/beta.o      \
1708   $(MESS_FORMATS)/spec_snqk.o \
1709   $(MESS_FORMATS)/timex_dck.o \
1708   $(MESS_MACHINE)/spec_snqk.o \
17101709   $(MESS_DRIVERS)/ql.o        \
17111710   $(MESS_VIDEO)/zx8301.o      \
17121711   $(MESS_MACHINE)/zx8302.o    \
trunk/src/mess/machine/sorcerer.c
r21309r21310
55*******************************************************************************/
66
77#include "includes/sorcerer.h"
8#include "machine/z80bin.h"
89
910#if SORCERER_USING_RS232
1011
r21309r21310
418419   membank("boot")->set_entry(1);
419420   machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(sorcerer_state::sorcerer_reset),this));
420421}
422
423
424/*-------------------------------------------------
425    QUICKLOAD_LOAD( sorcerer )
426-------------------------------------------------*/
427
428QUICKLOAD_LOAD( sorcerer )
429{
430   UINT16 execute_address, start_address, end_address;
431   int autorun;
432   /* load the binary into memory */
433   if (z80bin_load_file(&image, file_type, &execute_address, &start_address, &end_address) == IMAGE_INIT_FAIL)
434      return IMAGE_INIT_FAIL;
435
436   /* is this file executable? */
437   if (execute_address != 0xffff)
438   {
439      /* check to see if autorun is on (I hate how this works) */
440      autorun = image.device().machine().root_device().ioport("CONFIG")->read_safe(0xFF) & 1;
441
442      address_space &space = image.device().machine().device("maincpu")->memory().space(AS_PROGRAM);
443
444      if ((execute_address >= 0xc000) && (execute_address <= 0xdfff) && (space.read_byte(0xdffa) != 0xc3))
445         return IMAGE_INIT_FAIL;     /* can't run a program if the cartridge isn't in */
446
447      /* Since Exidy Basic is by Microsoft, it needs some preprocessing before it can be run.
448      1. A start address of 01D5 indicates a basic program which needs its pointers fixed up.
449      2. If autorunning, jump to C689 (command processor), else jump to C3DD (READY prompt).
450      Important addresses:
451          01D5 = start (load) address of a conventional basic program
452          C858 = an autorun basic program will have this exec address on the tape
453          C3DD = part of basic that displays READY and lets user enter input */
454
455      if ((start_address == 0x1d5) || (execute_address == 0xc858))
456      {
457         UINT8 i;
458         static const UINT8 data[]={
459            0xcd, 0x26, 0xc4,   // CALL C426    ;set up other pointers
460            0x21, 0xd4, 1,      // LD HL,01D4   ;start of program address (used by C689)
461            0x36, 0,        // LD (HL),00   ;make sure dummy end-of-line is there
462            0xc3, 0x89, 0xc6    // JP C689  ;run program
463         };
464
465         for (i = 0; i < ARRAY_LENGTH(data); i++)
466            space.write_byte(0xf01f + i, data[i]);
467
468         if (!autorun)
469            space.write_word(0xf028,0xc3dd);
470
471         /* tell BASIC where program ends */
472         space.write_byte(0x1b7, end_address & 0xff);
473         space.write_byte(0x1b8, (end_address >> 8) & 0xff);
474
475         if ((execute_address != 0xc858) && autorun)
476            space.write_word(0xf028, execute_address);
477
478         image.device().machine().device("maincpu")->state().set_pc(0xf01f);
479      }
480      else
481      {
482         if (autorun)
483            image.device().machine().device("maincpu")->state().set_pc(execute_address);
484      }
485
486   }
487
488   return IMAGE_INIT_PASS;
489}
trunk/src/mess/machine/spec_snqk.c
r0r21310
1/***************************************************************************
2
3  mess/machine/spec_snqk.c
4
5  TODO:
6
7    - Implement the following snapshot formats
8      .89C (Tezxas)
9      .SLT (Various emulators)
10      .SZX (Spectaculator)
11      .ZLS (ZX-Live!)
12      .ZX (ZXSpectr)
13      .ZX82 (Speculator '97)
14      .ZXS (ZX32)
15
16    - Implement the following quickload formats
17      .$? (HoBeta)
18      .__? (SpecEm)
19      .BAS (BASin)
20      .H/.B (Roman ZX)
21      .RAW (Various emulators)
22      .SCR variants
23
24    - Cleanup of the .Z80 format
25
26***************************************************************************/
27
28#include "emu.h"
29#include "ui.h"
30#include "cpu/z80/z80.h"
31#include "includes/spectrum.h"
32#include "sound/ay8910.h"
33#include "machine/spec_snqk.h"
34
35#define LOAD_REG(_cpu, _reg, _data) \
36      do { \
37         _cpu->state().set_state_int(_reg, (_data)); \
38      } while (0)
39
40#define EXEC_NA "N/A"
41
42/*-------------------------------------------------
43    log_quickload - logs and displays useful
44    data for the end user
45-------------------------------------------------*/
46
47static void log_quickload(const char *type, UINT32 start, UINT32 length, UINT32 exec, const char *exec_format)
48{
49   astring tempstring;
50
51   logerror("Loading %04X bytes of RAM at %04X\n", length, start);
52
53   tempstring.catprintf("Quickload type: %s   Length: %d bytes\n", type, length);
54   tempstring.catprintf("Start: 0x%04X   End: 0x%04X   Exec: ", start, start + length - 1);
55
56   logerror("Quickload loaded.\n");
57   if (!mame_stricmp(exec_format, EXEC_NA))
58      tempstring.cat("N/A");
59   else
60   {
61      logerror("Execution can resume with ");
62      logerror(exec_format, exec);
63      logerror("\n");
64      tempstring.catprintf(exec_format, exec);
65   }
66
67   ui_popup_time(10, "%s", tempstring.cstr());
68}
69
70/*******************************************************************
71 *
72 *      Update the memory and paging of the spectrum being emulated
73 *
74 *      if port_7ffd_data is -1 then machine is 48K - no paging
75 *      if port_1ffd_data is -1 then machine is 128K
76 *      if neither port is -1 then machine is +2a/+3
77 *
78 *      Note: the 128K .SNA and .Z80 file formats do not store the
79 *      port 1FFD setting so it is necessary to calculate the appropriate
80 *      value for the ROM paging.
81 *
82 *******************************************************************/
83static void spectrum_update_paging(running_machine &machine)
84{
85   spectrum_state *state = machine.driver_data<spectrum_state>();
86   if (state->m_port_7ffd_data == -1)
87      return;
88   if (state->m_port_1ffd_data == -1)
89      state->spectrum_128_update_memory();
90
91   else
92   {
93      if (BIT(state->m_port_7ffd_data, 4))
94         /* Page in Spec 48K basic ROM */
95         state->m_port_1ffd_data = 0x04;
96      else
97         state->m_port_1ffd_data = 0x00;
98      state->spectrum_plus3_update_memory();
99   }
100}
101
102/* Page in the 48K Basic ROM. Used when running 48K snapshots on a 128K machine. */
103static void spectrum_page_basicrom(running_machine &machine)
104{
105   spectrum_state *state = machine.driver_data<spectrum_state>();
106   if (state->m_port_7ffd_data == -1)
107      return;
108   state->m_port_7ffd_data |= 0x10;
109   spectrum_update_paging(machine);
110}
111
112
113SNAPSHOT_LOAD(spectrum)
114{
115   UINT8 *snapshot_data = NULL;
116
117   snapshot_data = (UINT8*)malloc(snapshot_size);
118   if (!snapshot_data)
119      goto error;
120
121   image.fread(snapshot_data, snapshot_size);
122
123   if (!mame_stricmp(file_type, "sna"))
124   {
125      if ((snapshot_size != SNA48_SIZE) && (snapshot_size != SNA128_SIZE_1) && (snapshot_size != SNA128_SIZE_2))
126      {
127         logerror("Invalid .SNA file size.\n");
128         goto error;
129      }
130      spectrum_setup_sna(image.device().machine(), snapshot_data, snapshot_size);
131   }
132   else if (!mame_stricmp(file_type, "sp"))
133   {
134      if ((snapshot_data[0] != 'S' && snapshot_data[1] != 'P') && (snapshot_size != SP_NEW_SIZE_16K && snapshot_size != SP_NEW_SIZE_48K))
135      {
136         if (snapshot_size != SP_OLD_SIZE)
137         {
138            logerror("Invalid .SP file size.\n");
139            goto error;
140         }
141      }
142      spectrum_setup_sp(image.device().machine(), snapshot_data, snapshot_size);
143   }
144   else if (!mame_stricmp(file_type, "ach"))
145   {
146      if (snapshot_size != ACH_SIZE)
147      {
148         logerror("Invalid .ACH file size.\n");
149         goto error;
150      }
151      spectrum_setup_ach(image.device().machine(), snapshot_data, snapshot_size);
152   }
153   else if (!mame_stricmp(file_type, "prg"))
154   {
155      if (snapshot_size != PRG_SIZE)
156      {
157         logerror("Invalid .PRG file size.\n");
158         goto error;
159      }
160      spectrum_setup_prg(image.device().machine(), snapshot_data, snapshot_size);
161   }
162   else if (!mame_stricmp(file_type, "plusd"))
163   {
164      if ((snapshot_size != PLUSD48_SIZE) && (snapshot_size != PLUSD128_SIZE))
165      {
166         logerror("Invalid .PLUSD file size.\n");
167         goto error;
168      }
169      spectrum_setup_plusd(image.device().machine(), snapshot_data, snapshot_size);
170   }
171   else if (!mame_stricmp(file_type, "sem"))
172   {
173      if (snapshot_data[0] != 0x05 && snapshot_data[1] != 'S' && \
174         snapshot_data[2] != 'P' && snapshot_data[3] != 'E' && \
175         snapshot_data[4] != 'C' && snapshot_data[5] != '1')
176      {
177         if (snapshot_size != SEM_SIZE)
178         {
179            logerror("Invalid .SEM file size.\n");
180            goto error;
181         }
182      }
183      spectrum_setup_sem(image.device().machine(), snapshot_data, snapshot_size);
184   }
185   else if (!mame_stricmp(file_type, "sit"))
186   {
187      if (snapshot_size != SIT_SIZE)
188      {
189         logerror("Invalid .SIT file size.\n");
190         goto error;
191      }
192      spectrum_setup_sit(image.device().machine(), snapshot_data, snapshot_size);
193   }
194   else if (!mame_stricmp(file_type, "zx"))
195   {
196      if (snapshot_size != ZX_SIZE)
197      {
198         logerror("Invalid .ZX file size.\n");
199         goto error;
200      }
201      spectrum_setup_zx(image.device().machine(), snapshot_data, snapshot_size);
202   }
203   else if (!mame_stricmp(file_type, "snp"))
204   {
205      if (snapshot_size != SNP_SIZE)
206      {
207         logerror("Invalid .SNP file size.\n");
208         goto error;
209      }
210      spectrum_setup_snp(image.device().machine(), snapshot_data, snapshot_size);
211   }
212   else if (!mame_stricmp(file_type, "snx"))
213   {
214      if (snapshot_data[0] != 'X' && snapshot_data[1] != 'S' && \
215         snapshot_data[2] != 'N' && snapshot_data[3] != 'A')
216      {
217         logerror("Invalid .SNX file size.\n");
218         goto error;
219      }
220      spectrum_setup_snx(image.device().machine(), snapshot_data, snapshot_size);
221   }
222   else if (!mame_stricmp(file_type, "frz"))
223   {
224      if (snapshot_size != FRZ_SIZE)
225      {
226         logerror("Invalid .FRZ file size.\n");
227         goto error;
228      }
229      spectrum_setup_frz(image.device().machine(), snapshot_data, snapshot_size);
230   }
231   else
232   {
233      spectrum_setup_z80(image.device().machine(), snapshot_data, snapshot_size);
234   }
235
236   free(snapshot_data);
237
238   return IMAGE_INIT_PASS;
239
240error:
241   if (snapshot_data)
242      free(snapshot_data);
243   return IMAGE_INIT_FAIL;
244}
245
246/*******************************************************************
247 *
248 *      Load a .SP file.
249 *
250 *      There are two kinds of .SP files: "old" and "new".
251 *
252 *      The old version is always 49184 bytes long and is created
253 *      by a leaked copy of the VGASpec emulator.
254 *
255 *      Subsequently Pedro Gimeno (the author of VGASpec) renamed it
256 *      to "Spectrum" (but it's colloquially known as the "Spanish
257 *      Spectrum emulator") and extended the header to break backward
258 *      compatibility: the new format supports both 16K and 48K
259 *      images and it's 16422 or 49190 bytes long.
260 *
261 *      http://www.formauri.es/personal/pgimeno/spec/spec.html
262 *
263 *      The formats are defined as follows:
264 *
265 *      Offset              Size    Description (all registers stored with LSB first)
266 *      ------------------- ------- -------------------------------------------------
267 *      VGASPEC SPECTRUM
268 *      ------------------- ------- -------------------------------------------------
269 *      N/A     0           2       "SP" (signature)
270 *      N/A     2           2       Program length
271 *      N/A     4           2       Program location
272 *      0       6           2       BC
273 *      2       8           2       DE
274 *      4       10          2       HL
275 *      6       12          2       AF
276 *      8       14          2       IX
277 *      10      16          2       IY
278 *      12      18          2       BC'
279 *      14      20          2       DE'
280 *      16      22          2       HL'
281 *      18      24          2       AF'
282 *      20      26          1       R
283 *      21      27          1       I
284 *      22      28          2       SP
285 *      24      30          2       PC
286 *      26      32          2       0x00 (reserved for future use)
287 *      28      34          1       Border color
288 *      29      35          1       0x00 (reserved for future use)
289 *      30      36          2       Status word
290 *      32      38          16384/  RAM dump
291 *                          49152
292 *
293 *  Status word:
294 *  Bit     Description
295 *  ------- ---------------------------------------------------
296 *  15-8    Reserved for future use
297 *  7-6     Reserved for internal use (0)
298 *  5       Status of the flash attribute: 0=normal/1=inverse
299 *  4       Interrupt pending for execution
300 *  3       If 1, IM 0; if 0, bit 1 determines interrupt mode
301 *              (Spectrum v0.99e had this behaviour reversed,
302 *              and this bit was not used in versions previous
303 *              to v 0.99e)
304 *  2       IFF2: 0=DI/1=EI
305 *  1       Interrupt mode (if bit 3 reset): 0=IM1/1=IM2
306 *  0       IFF1: 0=DI/1=EI
307 *
308 *******************************************************************/
309static void spectrum_border_update(running_machine &machine, int data)
310{
311#if 0
312   spectrum_EventList_Reset(machine);
313   spectrum_border_set_last_color(machine, data);
314   spectrum_border_force_redraw(machine);
315#endif
316}
317
318void spectrum_setup_sp(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
319{
320   int i, SP_OFFSET;
321   UINT8 intr;
322   UINT16 start, size, data, status;
323   spectrum_state *state = machine.driver_data<spectrum_state>();
324   device_t *cpu = machine.device("maincpu");
325   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
326
327   if (snapsize == SP_NEW_SIZE_16K || snapsize == SP_NEW_SIZE_48K)
328   {
329      SP_OFFSET = 0;
330      start = (snapdata[SP_OFFSET +  5] << 8) | snapdata[SP_OFFSET +  4];
331      size = (snapdata[SP_OFFSET +  3] << 8) | snapdata[SP_OFFSET +  2];
332   }
333   else
334   {
335      SP_OFFSET = SP_OLD_HDR - SP_NEW_HDR;
336      start = BASE_RAM;
337      size = 3*SPECTRUM_BANK;
338   }
339
340   data = (snapdata[SP_OFFSET + 13] << 8) | snapdata[SP_OFFSET + 12];
341   LOAD_REG(cpu, Z80_AF, data);
342
343   data = (snapdata[SP_OFFSET +  7] << 8) | snapdata[SP_OFFSET +  6];
344   LOAD_REG(cpu, Z80_BC, data);
345
346   data = (snapdata[SP_OFFSET +  9] << 8) | snapdata[SP_OFFSET +  8];
347   LOAD_REG(cpu, Z80_DE, data);
348
349   data = (snapdata[SP_OFFSET + 11] << 8) | snapdata[SP_OFFSET + 10];
350   LOAD_REG(cpu, Z80_HL, data);
351
352
353   data = (snapdata[SP_OFFSET + 25] << 8) | snapdata[SP_OFFSET + 24];
354   LOAD_REG(cpu, Z80_AF2, data);
355
356   data = (snapdata[SP_OFFSET + 19] << 8) | snapdata[SP_OFFSET + 18];
357   LOAD_REG(cpu, Z80_BC2, data);
358
359   data = (snapdata[SP_OFFSET + 21] << 8) | snapdata[SP_OFFSET + 20];
360   LOAD_REG(cpu, Z80_DE2, data);
361
362   data = (snapdata[SP_OFFSET + 23] << 8) | snapdata[SP_OFFSET + 22];
363   LOAD_REG(cpu, Z80_HL2, data);
364
365
366   data = (snapdata[SP_OFFSET + 15] << 8) | snapdata[SP_OFFSET + 14];
367   LOAD_REG(cpu, Z80_IX, data);
368
369   data = (snapdata[SP_OFFSET + 17] << 8) | snapdata[SP_OFFSET + 16];
370   LOAD_REG(cpu, Z80_IY, data);
371
372
373   data = snapdata[SP_OFFSET + 26];
374   LOAD_REG(cpu, Z80_R, data);
375
376   data = snapdata[SP_OFFSET + 27];
377   LOAD_REG(cpu, Z80_I, data);
378
379
380   data = (snapdata[SP_OFFSET + 29] << 8) | snapdata[SP_OFFSET + 28];
381   LOAD_REG(cpu, Z80_SP, data);
382
383   data = (snapdata[SP_OFFSET + 31] << 8) | snapdata[SP_OFFSET + 30];
384   LOAD_REG(cpu, Z80_PC, data);
385
386
387   status = (snapdata[SP_OFFSET + 37] << 8) | snapdata[SP_OFFSET + 36];
388
389   data = (BIT(status, 3) << 1) | BIT(status, 1);
390   switch(data)
391   {
392      case 0: // case 2: in version 0.99e of the emulator
393      LOAD_REG(cpu, Z80_IM, 1);
394      break;
395      case 1: // case 3: in version 0.99e of the emulator
396      LOAD_REG(cpu, Z80_IM, 2);
397      break;
398      case 2: // case 0: in version 0.99e of the emulator
399      case 3: // case 1: in version 0.99e of the emulator
400      LOAD_REG(cpu, Z80_IM, (UINT64)0);
401   }
402
403   data = BIT(status, 0);
404   LOAD_REG(cpu, Z80_IFF1, data);
405
406   data = BIT(status, 2);
407   LOAD_REG(cpu, Z80_IFF2, data);
408
409   intr = BIT(status, 4) ? ASSERT_LINE : CLEAR_LINE;
410   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
411   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
412
413   data = BIT(status, 5);
414   state->m_flash_invert = data;
415   logerror("FLASH state: %s\n", data ? "PAPER on INK" : "INK on PAPER");
416
417   /* Memory dump */
418   logerror("Loading %04X bytes of RAM at %04X\n", size, start);
419   for (i = 0; i < size; i++)
420      space.write_byte(start + i, snapdata[SP_OFFSET + SP_NEW_HDR + i]);
421
422   /* Set border color */
423   data = snapdata[SP_OFFSET + 34] & 0x07;
424   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
425   spectrum_border_update(machine, data);
426   logerror("Border color:%02X\n", data);
427
428   spectrum_page_basicrom(machine);
429
430   //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
431}
432
433/*******************************************************************
434 *
435 *      Load a .SNA file.
436 *
437 *      This format was used by Arnt Gulbrandsen for its JPP
438 *      emulator, and it's based on the format used by the Mirage
439 *      Microdriver, a Microdrive backup accessory.
440 *
441 *      http://www.worldofspectrum.org/infoseekid.cgi?id=1000266
442 *
443 *      The 48K image is always 49179 bytes long.
444 *
445 *      .SNA snapshots save the PC on the top of the stack, thus
446 *      deleting the original bytes: not a good feature for a snapshot...
447 *
448 *      It's been reported that snapshots saved at critical moments would
449 *      subsequently crash on restore due to the fact that the stack was full
450 *      or pointed to a ROM address. A workaround for this situation is to
451 *      store 0x0000 into the word where the PC was located.
452 *
453 *      For sake of fidelity, the code that zeroes the top of the stack has
454 *      been written but commented out.
455 *
456 *      Later, the format has been extended to store the whole Spectrum 128 status.
457 *
458 *      48K format as follows:
459 *
460 *      Offset  Size    Description (all registers stored with LSB first)
461 *      ------- ------- -------------------------------------------------
462 *      0       1       I
463 *      1       2       HL'
464 *      3       2       DE'
465 *      5       2       BC'
466 *      7       2       AF'
467 *      9       2       HL
468 *      11      2       DE
469 *      13      2       BC
470 *      15      2       IY
471 *      17      2       IX
472 *      19      1       IFF1/2: bit 0 contains IFF1, bit 2 contains IFF2 (0=DI/1=EI)
473 *      20      1       R
474 *      21      2       AF
475 *      23      2       SP
476 *      25      1       Interrupt mode (0=IM0/1=IM1/2=IM2)
477 *      26      1       Border color
478 *      27      49152   RAM dump
479 *
480 *      PC is stored on stack.
481 *
482 *      128K format as follows:
483 *
484 *      Offset  Size    Description (all registers stored with LSB first)
485 *      ------- ------- -------------------------------------------------
486 *      0       1       I
487 *      1       2       HL'
488 *      3       2       DE'
489 *      5       2       BC'
490 *      7       2       AF'
491 *      9       2       HL
492 *      11      2       DE
493 *      13      2       BC
494 *      15      2       IY
495 *      17      2       IX
496 *      19      1       IFF1/2: bit 0 contains IFF1, bit 2 contains IFF2 (0=DI/1=EI)
497 *      20      1       R
498 *      21      2       AF
499 *      23      2       SP
500 *      25      1       Interrupt mode (0=IM0/1=IM1/2=IM2)
501 *      26      1       Border color
502 *      27      16384   RAM bank 5 (0x4000-0x7fff)
503 *      16411   16384   RAM bank 2 (0x8000-0xbfff)
504 *      32795   16384   RAM bank n (0xc000-0xffff - currently paged bank)
505 *      49179   2       PC
506 *      49181   1       Port 0x7FFD data
507 *      49182   1       TR-DOS rom paged (0=no/1=yes)
508 *      49183   81920/  Remaining RAM banks in ascending order
509 *              98304
510 *
511 *      PC is NOT stored on stack.
512 *
513 *      The bank in 0xc000 is always included even if it is page 2 or 5
514 *      in which case it is included twice.
515 *
516 *******************************************************************/
517void spectrum_setup_sna(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
518{
519   int i, j, usedbanks[8];
520   long bank_offset;
521   UINT8 intr;
522   UINT16 data, addr;
523   spectrum_state *state = machine.driver_data<spectrum_state>();
524   device_t *cpu = machine.device("maincpu");
525   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
526
527   if ((snapsize != SNA48_SIZE) && (state->m_port_7ffd_data == -1))
528   {
529      logerror("Can't load 128K .SNA file into 48K machine\n");
530      return;
531   }
532
533
534   data = (snapdata[SNA48_OFFSET + 22] << 8) | snapdata[SNA48_OFFSET + 21];
535   LOAD_REG(cpu, Z80_AF, data);
536
537   data = (snapdata[SNA48_OFFSET + 14] << 8) | snapdata[SNA48_OFFSET + 13];
538   LOAD_REG(cpu, Z80_BC, data);
539
540   data = (snapdata[SNA48_OFFSET + 12] << 8) | snapdata[SNA48_OFFSET + 11];
541   LOAD_REG(cpu, Z80_DE, data);
542
543   data = (snapdata[SNA48_OFFSET + 10] << 8) | snapdata[SNA48_OFFSET +  9];
544   LOAD_REG(cpu, Z80_HL, data);
545
546
547   data = (snapdata[SNA48_OFFSET +  8] << 8) | snapdata[SNA48_OFFSET +  7];
548   LOAD_REG(cpu, Z80_AF2, data);
549
550   data = (snapdata[SNA48_OFFSET +  6] << 8) | snapdata[SNA48_OFFSET +  5];
551   LOAD_REG(cpu, Z80_BC2, data);
552
553   data = (snapdata[SNA48_OFFSET +  4] << 8) | snapdata[SNA48_OFFSET +  3];
554   LOAD_REG(cpu, Z80_DE2, data);
555
556   data = (snapdata[SNA48_OFFSET +  2] << 8) | snapdata[SNA48_OFFSET +  1];
557   LOAD_REG(cpu, Z80_HL2, data);
558
559
560   data = (snapdata[SNA48_OFFSET + 18] << 8) | snapdata[SNA48_OFFSET + 17];
561   LOAD_REG(cpu, Z80_IX, data);
562
563   data = (snapdata[SNA48_OFFSET + 16] << 8) | snapdata[SNA48_OFFSET + 15];
564   LOAD_REG(cpu, Z80_IY, data);
565
566
567   data = snapdata[SNA48_OFFSET + 20];
568   LOAD_REG(cpu, Z80_R, data);
569
570   data = snapdata[SNA48_OFFSET +  0];
571   LOAD_REG(cpu, Z80_I, data);
572
573
574   data = (snapdata[SNA48_OFFSET + 24] << 8) | snapdata[SNA48_OFFSET + 23];
575   LOAD_REG(cpu, Z80_SP, data);
576
577
578   data = snapdata[SNA48_OFFSET + 25] & 0x03;
579   if (data == 3)
580      data = 2;
581   LOAD_REG(cpu, Z80_IM, data);
582
583   data = snapdata[SNA48_OFFSET + 19];
584   LOAD_REG(cpu, Z80_IFF1, BIT(data, 0));
585   LOAD_REG(cpu, Z80_IFF2, BIT(data, 2));
586
587   intr = BIT(data, 0) ? CLEAR_LINE : ASSERT_LINE;
588   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
589   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
590
591   if (snapsize == SNA48_SIZE)
592      /* 48K Snapshot */
593      spectrum_page_basicrom(machine);
594   else
595   {
596      /* 128K Snapshot */
597      state->m_port_7ffd_data = snapdata[SNA128_OFFSET + 2];
598      logerror ("Port 7FFD:%02X\n", state->m_port_7ffd_data);
599      if (snapdata[SNA128_OFFSET + 3])
600      {
601         /* TODO: page TR-DOS ROM when supported */
602      }
603      spectrum_update_paging(machine);
604   }
605
606   if (snapsize == SNA48_SIZE)
607   {
608      /* Memory dump */
609      logerror("Loading %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
610      for (i = 0; i < 3*SPECTRUM_BANK; i++)
611         space.write_byte(BASE_RAM + i, snapdata[SNA48_HDR + i]);
612
613      /* Get PC from stack */
614      addr = cpu->state().state_int(Z80_SP);
615
616      if (addr < BASE_RAM || addr > 4*SPECTRUM_BANK - 2)
617         logerror("Corrupted SP out of range:%04X", addr);
618      else
619         logerror("Fetching PC from the stack at SP:%04X\n", addr);
620
621      data = (space.read_byte(addr + 1) << 8) | space.read_byte(addr + 0);
622      LOAD_REG(cpu, Z80_PC, data);
623
624#if 0
625      space.write_byte(addr + 0, 0); // It's been reported that zeroing these locations fixes the loading
626      space.write_byte(addr + 1, 0); // of a few images that were snapshot at a "wrong" instant
627#endif
628
629      addr += 2;
630      logerror("Fixing SP:%04X\n", addr);
631      cpu->state().set_state_int(Z80_SP, addr);
632
633      /* Set border color */
634      data = snapdata[SNA48_OFFSET + 26] & 0x07;
635      state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
636   spectrum_border_update(machine, data);
637      logerror("Border color:%02X\n", data);
638
639      //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
640   }
641   else
642   {
643      /* Set up other RAM banks */
644      for (i = 0; i < 8; i++)
645         usedbanks[i] = 0;
646
647      usedbanks[5] = 1;                               /* 0x4000-0x7fff */
648      usedbanks[2] = 1;                               /* 0x8000-0xbfff */
649      usedbanks[state->m_port_7ffd_data & 0x07] = 1;    /* Banked memory */
650
651      logerror("Loading %05X bytes of RAM at %04X\n", 8*SPECTRUM_BANK, BASE_RAM);
652      logerror("Loading bank 5 from offset:0001B\n");
653      logerror("Loading bank 2 from offset:0401B\n");
654      logerror("Loading bank %d from offset:0801B\n", snapdata[SNA128_OFFSET + 2] & 0x07);
655      for (i = 0; i < 3*SPECTRUM_BANK; i++)
656         space.write_byte(BASE_RAM + i, snapdata[SNA48_HDR + i]);
657
658      bank_offset = SNA48_SIZE + SNA128_HDR;
659      for (i = 0; i < 8; i++)
660      {
661         if (!usedbanks[i])
662         {
663            logerror("Loading bank %d from offset:%05lX\n", i, bank_offset);
664            state->m_port_7ffd_data &= 0xf8;
665            state->m_port_7ffd_data += i;
666            spectrum_update_paging(machine);
667            for (j = 0; j < SPECTRUM_BANK; j++)
668               space.write_byte(j + 3*SPECTRUM_BANK, snapdata[bank_offset + j]);
669            bank_offset += SPECTRUM_BANK;
670         }
671      }
672
673      /* program counter */
674      data = (snapdata[SNA128_OFFSET + 1] << 8) | snapdata[SNA128_OFFSET + 0];
675      LOAD_REG(cpu, Z80_PC, data);
676
677      /* Set border color */
678      data = snapdata[SNA48_OFFSET + 26] & 0x07;
679      state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
680   spectrum_border_update(machine, data);
681      logerror("Border color:%02X\n", data);
682      data = state->m_port_7ffd_data & 0x07;
683
684      /* Reset paging */
685      state->m_port_7ffd_data = snapdata[SNA128_OFFSET + 2];
686      spectrum_update_paging(machine);
687
688      //logerror("Snapshot loaded.\nExecution resuming at bank:%d %s\n", data, cpu_get_reg_string(cpu, Z80_PC));
689   }
690}
691
692/*******************************************************************
693 *
694 *      Load a .ACH file.
695 *
696 *      .ACH files were produced by a commercial Archimedes
697 *      (hence the name) emulator called !Speccy.
698 *
699 *      The files are always 65792 bytes long and store both
700 *      a copy of the ROM and the whole 48K RAM.
701 *
702 *
703 *      Offset  Size    Description (all registers stored with LSB first
704 *                      except when noted with *BE*)
705 *      ------- ------- -------------------------------------------------
706 *      0       4       A
707 *      4       4       F
708 *      8       4       B
709 *      12      4       C
710 *      16      4       D
711 *      20      4       E
712 *      24      4       H
713 *      28      4       L
714 *      32      4       PC
715 *      36      4       0x00 (reserved for future use)
716 *      40      4       SP
717 *      44      104     0x00 (reserved for future use)
718 *      148     4       R
719 *      152     4       0x00 (reserved for future use)
720 *      156     4       Border color
721 *      160     4       0x00 (reserved for future use)
722 *      164     2       Interrupt mode (0=IM0/1=IM1/2=IM2)
723 *      166     24      0x00 (reserved for future use)
724 *      190     1       I
725 *      191     1       IFF1/2: (0=DI/1=EI)
726 *      192     44      0x00 (reserved for future use)
727 *      236     4       AF' *BE*
728 *      240     4       BC' *BE*
729 *      244     2       DE' *BE*
730 *      246     2       HL' *BE*
731 *      248     4       IX
732 *      252     4       IY
733 *      256     16384   ROM dump
734 *      16640   49152   RAM dump
735 *
736 *******************************************************************/
737void spectrum_setup_ach(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
738{
739   int i;
740   UINT8 intr;
741   UINT16 data;
742   spectrum_state *state = machine.driver_data<spectrum_state>();
743   device_t *cpu = machine.device("maincpu");
744   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
745
746   data = (snapdata[ACH_OFFSET +   0] << 8) | snapdata[ACH_OFFSET +   4];
747   LOAD_REG(cpu, Z80_AF, data);
748
749   data = (snapdata[ACH_OFFSET +   8] << 8) | snapdata[ACH_OFFSET +  12];
750   LOAD_REG(cpu, Z80_BC, data);
751
752   data = (snapdata[ACH_OFFSET +  16] << 8) | snapdata[ACH_OFFSET +  20];
753   LOAD_REG(cpu, Z80_DE, data);
754
755   data = (snapdata[ACH_OFFSET +  24] << 8) | snapdata[ACH_OFFSET +  28];
756   LOAD_REG(cpu, Z80_HL, data);
757
758
759   data = (snapdata[ACH_OFFSET + 236] << 8) | snapdata[ACH_OFFSET + 237];
760   LOAD_REG(cpu, Z80_AF2, data);
761
762   data = (snapdata[ACH_OFFSET + 240] << 8) | snapdata[ACH_OFFSET + 241];
763   LOAD_REG(cpu, Z80_BC2, data);
764
765   data = (snapdata[ACH_OFFSET + 244] << 8) | snapdata[ACH_OFFSET + 245];
766   LOAD_REG(cpu, Z80_DE2, data);
767
768   data = (snapdata[ACH_OFFSET + 246] << 8) | snapdata[ACH_OFFSET + 247];
769   LOAD_REG(cpu, Z80_HL2, data);
770
771
772   data = (snapdata[ACH_OFFSET + 249] << 8) | snapdata[ACH_OFFSET + 248];
773   LOAD_REG(cpu, Z80_IX, data);
774
775   data = (snapdata[ACH_OFFSET + 253] << 8) | snapdata[ACH_OFFSET + 252];
776   LOAD_REG(cpu, Z80_IY, data);
777
778   data = snapdata[ACH_OFFSET + 148];
779   LOAD_REG(cpu, Z80_R, data);
780
781   data = snapdata[ACH_OFFSET + 190];
782   LOAD_REG(cpu, Z80_I, data);
783
784
785   data = (snapdata[ACH_OFFSET +  41] << 8) | snapdata[ACH_OFFSET +  40];
786   LOAD_REG(cpu, Z80_SP, data);
787
788   data = (snapdata[ACH_OFFSET +  33] << 8) | snapdata[ACH_OFFSET +  32];
789   LOAD_REG(cpu, Z80_PC, data);
790
791   data = snapdata[ACH_OFFSET + 164] & 0x03;
792   if (data == 3)
793      data = 0;
794   LOAD_REG(cpu, Z80_IM, data);
795
796   data = snapdata[ACH_OFFSET + 191] ? 1 : 0;
797   LOAD_REG(cpu, Z80_IFF1, data);
798   LOAD_REG(cpu, Z80_IFF2, data);
799
800   intr = snapdata[ACH_OFFSET + 191] ? CLEAR_LINE : ASSERT_LINE;
801   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
802   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
803
804   logerror("Skipping the 16K ROM dump at offset:%04X\n", ACH_OFFSET + 256);
805
806   /* Memory dump */
807   logerror("Loading %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
808   for (i = 0; i < 3*SPECTRUM_BANK; i++)
809      space.write_byte(BASE_RAM + i, snapdata[ACH_HDR + SPECTRUM_BANK + i]);
810
811   /* Set border color */
812   data = snapdata[ACH_OFFSET + 156] & 0x07;
813   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
814   spectrum_border_update(machine, data);
815   logerror("Border color:%02X\n", data);
816
817   spectrum_page_basicrom(machine);
818
819   //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
820}
821
822/*******************************************************************
823 *
824 *      Load a .PRG file.
825 *
826 *      .PRG files were produced by an irish emulator called SpecEm
827 *      written by Kevin Phair (thanks for the help, Kevin!)
828 *
829 *      http://code.google.com/p/specem/
830 *
831 *      The files are always 49408 bytes long and use some stack space
832 *      to store registers.
833 *
834 *      The header actually mimics the file descriptor format used by
835 *      the DISCiPLE/+D interface.
836 *
837 *      Offset  Size    Description (all registers stored with LSB first
838 *                      except when noted with *BE*)
839 *      ------- ------- -------------------------------------------------
840 *      0       1       File type (always 0x05, corresponding to "48K Snapshot"
841 *      1       10      Program name (padded with 0x20)
842 *      11      2       Number of sectors occupied by the file *BE*
843 *      13      1       Track number of the first sector of the file
844 *      14      1       Sector number of the first sector of the file
845 *      15      195     Sector allocation bitmap
846 *      210     10      0x00 (reserved for future use)
847 *      220     2       IY
848 *      222     2       IX
849 *      224     2       DE'
850 *      226     2       BC'
851 *      228     2       HL'
852 *      230     2       AF'
853 *      232     2       DE
854 *      234     2       BC
855 *      236     2       HL
856 *      238     1       Junk created when saving I via LD A,I/PUSH AF
857 *      239     1       I
858 *      240     2       SP
859 *      242     14      0x00 (reserved for future use)
860 *      256     49152   RAM dump
861 *
862 *      IFF1/2, R, AF and PC are stored on the stack. Due to a bug in the
863 *      BIOS, the snapshots created with the DISCiPLE have the AF' register
864 *      replaced with the AF register.
865 *
866 *      It's unknown (but likely possible) that the snapshots could
867 *      suffer from the same "top of the stack" bug as well as .SNA images.
868 *
869 *******************************************************************/
870void spectrum_setup_prg(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
871{
872   int i;
873   UINT8 intr;
874   UINT16 addr, data;
875   spectrum_state *state = machine.driver_data<spectrum_state>();
876   device_t *cpu = machine.device("maincpu");
877   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
878
879   data = snapdata[PRG_OFFSET +   0];
880   if (data != 0x05)
881      logerror("Wrong DISCiPLE/+D file type: %02X instead of 05\n", data);
882
883   data = (snapdata[PRG_OFFSET + 235] << 8) | snapdata[PRG_OFFSET + 234];
884   LOAD_REG(cpu, Z80_BC, data);
885
886   data = (snapdata[PRG_OFFSET + 233] << 8) | snapdata[PRG_OFFSET + 232];
887   LOAD_REG(cpu, Z80_DE, data);
888
889   data = (snapdata[PRG_OFFSET + 237] << 8) | snapdata[PRG_OFFSET + 236];
890   LOAD_REG(cpu, Z80_HL, data);
891
892
893   data = (snapdata[PRG_OFFSET + 231] << 8) | snapdata[PRG_OFFSET + 230];
894   LOAD_REG(cpu, Z80_AF2, data);
895
896   data = (snapdata[PRG_OFFSET + 227] << 8) | snapdata[PRG_OFFSET + 226];
897   LOAD_REG(cpu, Z80_BC2, data);
898
899   data = (snapdata[PRG_OFFSET + 225] << 8) | snapdata[PRG_OFFSET + 224];
900   LOAD_REG(cpu, Z80_DE2, data);
901
902   data = (snapdata[PRG_OFFSET + 229] << 8) | snapdata[PRG_OFFSET + 228];
903   LOAD_REG(cpu, Z80_HL2, data);
904
905
906   data = (snapdata[PRG_OFFSET + 223] << 8) | snapdata[PRG_OFFSET + 222];
907   LOAD_REG(cpu, Z80_IX, data);
908
909   data = (snapdata[PRG_OFFSET + 221] << 8) | snapdata[PRG_OFFSET + 220];
910   LOAD_REG(cpu, Z80_IY, data);
911
912   data = snapdata[PRG_OFFSET + 239];
913   LOAD_REG(cpu, Z80_I, data);
914
915   LOAD_REG(cpu, Z80_IM, (data == 0x00 || data == 0x3f) ? 1 : 2);
916
917   /* Memory dump */
918   logerror("Loading %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
919   for (i = 0; i < 3*SPECTRUM_BANK; i++)
920      space.write_byte(BASE_RAM + i, snapdata[PRG_HDR + i]);
921
922   addr = (snapdata[PRG_OFFSET + 241] << 8) | snapdata[PRG_OFFSET + 240];
923   if (addr < BASE_RAM || addr > 4*SPECTRUM_BANK - 6)
924      logerror("Corrupted SP out of range:%04X", addr);
925   else
926      logerror("Fetching registers IFF1/2, R, AF and PC from the stack at SP:%04X\n", addr);
927
928   data = space.read_byte(addr + 0); // IFF1/2: (bit 2, 0=DI/1=EI)
929   LOAD_REG(cpu, Z80_IFF1, BIT(data, 2));
930   LOAD_REG(cpu, Z80_IFF2, BIT(data, 2));
931
932   intr = BIT(data, 2) ? CLEAR_LINE : ASSERT_LINE;
933   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
934   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
935
936   data = space.read_byte(addr + 1);
937   LOAD_REG(cpu, Z80_R, data);
938
939   data = (space.read_byte(addr + 3) << 8) | space.read_byte(addr + 2);
940   LOAD_REG(cpu, Z80_AF, data);
941
942   data = (space.read_byte(addr + 5) << 8) | space.read_byte(addr + 4);
943   LOAD_REG(cpu, Z80_PC, data);
944
945#if 0
946   space.write_byte(addr + 0, 0); // It's been reported that zeroing these locations fixes the loading
947   space.write_byte(addr + 1, 0); // of a few images that were snapshot at a "wrong" instant
948   space.write_byte(addr + 2, 0);
949   space.write_byte(addr + 3, 0);
950   space.write_byte(addr + 4, 0);
951   space.write_byte(addr + 5, 0);
952#endif
953
954   addr += 6;
955   logerror("Fixing SP:%04X\n", addr);
956   cpu->state().set_state_int(Z80_SP, addr);
957
958   /* Set border color */
959   data = (space.read_byte(0x5c48) >> 3) & 0x07; // Get the current border color from BORDCR system variable.
960   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
961   spectrum_border_update(machine, data);
962   logerror("Border color:%02X\n", data);
963
964   spectrum_page_basicrom(machine);
965
966   //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
967}
968
969/*******************************************************************
970 *
971 *      Load a .PLUSD file.
972 *
973 *      .PLUSD files are the snapshots produced by the DISCiPLE or
974 *      the +D disk interface, thus share the same internal organization
975 *      of the .PRG files, with a couple of notable exceptions:
976 *
977 *      1) The filesystem metadata is missing
978 *      2) Spectrum 128 snapshots (file type 9) are allowed
979 *
980 *      A commented disassembly of both BIOSes is avilable at:
981 *
982 *      http://www.biehold.nl/rudy/
983 *
984 *      48K snapshots are 49174 bytes long, 128K snapshots are 131095
985 *      bytes long.
986 *
987 *      Philip Kendall's FUSE emulator at http://fuse-emulator.sourceforge.net
988 *      supports this format, but no extension is officially provided.
989 *      Therefore I have used .PLUSD - corrections are welcome!
990 *
991 *      48K snapshot format
992 *      -------------------
993 *
994 *      Offset  Size    Description (all registers stored with LSB first
995 *      ------- ------- -------------------------------------------------
996 *      0       2       IY
997 *      2       2       IX
998 *      4       2       DE'
999 *      6       2       BC'
1000 *      8       2       HL'
1001 *      10      2       AF'
1002 *      12      2       DE
1003 *      14      2       BC
1004 *      16      2       HL
1005 *      18      1       Junk created when saving I via LD A,I/PUSH AF
1006 *      19      1       I
1007 *      20      2       SP
1008 *      22      49152   RAM dump
1009 *
1010 *      128K snapshot format
1011 *      --------------------
1012 *
1013 *      Offset  Size    Description (all registers stored with LSB first
1014 *      ------- ------- -------------------------------------------------
1015 *      0       2       IY
1016 *      2       2       IX
1017 *      4       2       DE'
1018 *      6       2       BC'
1019 *      8       2       HL'
1020 *      10      2       AF'
1021 *      12      2       DE
1022 *      14      2       BC
1023 *      16      2       HL
1024 *      18      1       Junk created when saving I via LD A,I/PUSH AF
1025 *      19      1       I
1026 *      20      2       SP
1027 *      22      1       Port 0x7FFD data
1028 *      23      131072  RAM dump
1029 *
1030 *      The 8 RAM banks are stored in the order 0-7.
1031 *
1032 *      IFF1/2, R, AF and PC are stored on the stack. Due to a bug in the
1033 *      BIOS, the snapshots created with the DISCiPLE have the AF' register
1034 *      replaced with the AF register.
1035 *
1036 *      It's unknown (but likely possible) that the snapshots could
1037 *      suffer from the same "top of the stack" bug as well as .SNA images.
1038 *
1039 *******************************************************************/
1040void spectrum_setup_plusd(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
1041{
1042   int i, j;
1043   UINT8 intr;
1044   UINT16 addr = 0, data;
1045   spectrum_state *state = machine.driver_data<spectrum_state>();
1046   device_t *cpu = machine.device("maincpu");
1047   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1048
1049   data = (snapdata[PLUSD_OFFSET + 15] << 8) | snapdata[PLUSD_OFFSET + 14];
1050   LOAD_REG(cpu, Z80_BC, data);
1051
1052   data = (snapdata[PLUSD_OFFSET + 13] << 8) | snapdata[PLUSD_OFFSET + 12];
1053   LOAD_REG(cpu, Z80_DE, data);
1054
1055   data = (snapdata[PLUSD_OFFSET + 17] << 8) | snapdata[PLUSD_OFFSET + 16];
1056   LOAD_REG(cpu, Z80_HL, data);
1057
1058
1059   data = (snapdata[PLUSD_OFFSET + 11] << 8) | snapdata[PLUSD_OFFSET + 10];
1060   LOAD_REG(cpu, Z80_AF2, data);
1061
1062   data = (snapdata[PLUSD_OFFSET +  7] << 8) | snapdata[PLUSD_OFFSET +  6];
1063   LOAD_REG(cpu, Z80_BC2, data);
1064
1065   data = (snapdata[PLUSD_OFFSET +  5] << 8) | snapdata[PLUSD_OFFSET +  4];
1066   LOAD_REG(cpu, Z80_DE2, data);
1067
1068   data = (snapdata[PLUSD_OFFSET +  9] << 8) | snapdata[PLUSD_OFFSET +  8];
1069   LOAD_REG(cpu, Z80_HL2, data);
1070
1071
1072   data = (snapdata[PLUSD_OFFSET +  3] << 8) | snapdata[PLUSD_OFFSET +  2];
1073   LOAD_REG(cpu, Z80_IX, data);
1074
1075   data = (snapdata[PLUSD_OFFSET +  1] << 8) | snapdata[PLUSD_OFFSET +  0];
1076   LOAD_REG(cpu, Z80_IY, data);
1077
1078   data = snapdata[PLUSD_OFFSET + 19];
1079   LOAD_REG(cpu, Z80_I, data);
1080
1081   LOAD_REG(cpu, Z80_IM, (data == 0x00 || data == 0x3f) ? 1 : 2);
1082
1083   if (snapsize == PLUSD48_SIZE)
1084   {
1085      spectrum_page_basicrom(machine);
1086
1087      /* Memory dump */
1088      logerror("Loading %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
1089      for (i = 0; i < 3*SPECTRUM_BANK; i++)
1090         space.write_byte(BASE_RAM + i, snapdata[PLUSD48_HDR + i]);
1091   }
1092   else
1093   {
1094      logerror("Loading %05X bytes of RAM at %04X\n", 8*SPECTRUM_BANK, BASE_RAM);
1095      for (i = 0; i < 8; i++)
1096      {
1097         switch (i)
1098         {
1099            case 5: addr = SPECTRUM_BANK;
1100                  break;
1101            case 2: addr = 2*SPECTRUM_BANK;
1102                  break;
1103            case 0:
1104            case 1:
1105            case 3:
1106            case 4:
1107            case 6:
1108            case 7: addr = 3*SPECTRUM_BANK;
1109                  state->m_port_7ffd_data &= 0xf8;
1110                  state->m_port_7ffd_data += i;
1111                  spectrum_update_paging(machine);
1112                  break;
1113         };
1114         logerror("Loading bank %d from offset:%05X\n", i, PLUSD128_HDR + i*SPECTRUM_BANK);
1115         for (j = 0; j < SPECTRUM_BANK; j++)
1116            space.write_byte(j + addr, snapdata[j + PLUSD128_HDR + i*SPECTRUM_BANK]);
1117      }
1118      state->m_port_7ffd_data = snapdata[PLUSD_OFFSET + 22];
1119      logerror ("Port 7FFD:%02X\n", state->m_port_7ffd_data);
1120      logerror ("Paging bank:%d\n", state->m_port_7ffd_data & 0x07);
1121      spectrum_update_paging(machine);
1122   }
1123
1124   addr = (snapdata[PLUSD_OFFSET + 21] << 8) | snapdata[PLUSD_OFFSET + 20];
1125   if (addr < BASE_RAM || addr > 4*SPECTRUM_BANK - 6)
1126      logerror("Corrupted SP out of range:%04X", addr);
1127   else
1128      logerror("Fetching registers IFF1/2, R, AF and PC from the stack at SP:%04X\n", addr);
1129
1130   data = space.read_byte(addr + 0); // IFF1/2: (bit 2, 0=DI/1=EI)
1131   LOAD_REG(cpu, Z80_IFF1, BIT(data, 2));
1132   LOAD_REG(cpu, Z80_IFF2, BIT(data, 2));
1133
1134   intr = BIT(data, 2) ? CLEAR_LINE : ASSERT_LINE;
1135   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
1136   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
1137
1138   data = space.read_byte(addr + 1);
1139   LOAD_REG(cpu, Z80_R, data);
1140
1141   data = (space.read_byte(addr + 3) << 8) | space.read_byte(addr + 2);
1142   LOAD_REG(cpu, Z80_AF, data);
1143
1144   data = (space.read_byte(addr + 5) << 8) | space.read_byte(addr + 4);
1145   LOAD_REG(cpu, Z80_PC, data);
1146
1147#if 0
1148   space.write_byte(addr + 0, 0); // It's been reported that zeroing these locations fixes the loading
1149   space.write_byte(addr + 1, 0); // of a few images that were snapshot at a "wrong" instant
1150   space.write_byte(addr + 2, 0);
1151   space.write_byte(addr + 3, 0);
1152   space.write_byte(addr + 4, 0);
1153   space.write_byte(addr + 5, 0);
1154#endif
1155
1156   addr += 6;
1157   logerror("Fixing SP:%04X\n", addr);
1158   cpu->state().set_state_int(Z80_SP, addr);
1159
1160   /* Set border color */
1161   data = (space.read_byte(0x5c48) >> 3) & 0x07; // Get the current border color from BORDCR system variable.
1162   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
1163   spectrum_border_update(machine, data);
1164   logerror("Border color:%02X\n", data);
1165
1166   //if (snapsize == PLUSD48_SIZE)
1167      //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
1168   //else
1169      //logerror("Snapshot loaded.\nExecution resuming at bank:%d %s\n", state->m_port_7ffd_data & 0x07, cpu_get_reg_string(cpu, Z80_PC));
1170}
1171
1172/*******************************************************************
1173 *
1174 *      Load a .SEM file.
1175 *
1176 *      .SEM files were produced by a german emulator called SpecEmu
1177 *      written by Bernd Waschke.
1178 *
1179 *      The files are usually 49192 bytes long unless optional POKE
1180 *      blocks are stored at the end of the file.
1181 *
1182 *      Offset  Size    Description (all registers stored with LSB first)
1183 *      ------- ------- -------------------------------------------------
1184 *      0       1       0x05 (signature length)
1185 *      1       5       "SPEC1" (signature)
1186 *      6       49152   RAM dump
1187 *      49158   2       AF
1188 *      49160   2       BC
1189 *      49162   2       DE
1190 *      49164   2       HL
1191 *      49166   2       AF'
1192 *      49168   2       BC'
1193 *      49170   2       DE'
1194 *      49172   2       HL'
1195 *      49174   2       PC
1196 *      49176   2       SP
1197 *      49178   2       IX
1198 *      49180   2       IY
1199 *      49182   2       I
1200 *      49184   2       R
1201 *      49186   2       IFF1 (0=DI/1=EI)
1202 *      49188   2       IFF2 (0=DI/1=EI)
1203 *      49190   2       Interrupt mode (0=IM0/1=IM1/2=IM2)
1204 *
1205 *      Following these data, there are optional POKE blocks
1206 *
1207 *******************************************************************/
1208void spectrum_setup_sem(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
1209{
1210   int i;
1211   UINT8 intr;
1212   UINT16 data;
1213   spectrum_state *state = machine.driver_data<spectrum_state>();
1214   device_t *cpu = machine.device("maincpu");
1215   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1216
1217   data = (snapdata[SEM_OFFSET +  1] << 8) | snapdata[SEM_OFFSET +  0];
1218   LOAD_REG(cpu, Z80_AF, data);
1219
1220   data = (snapdata[SEM_OFFSET +  3] << 8) | snapdata[SEM_OFFSET +  2];
1221   LOAD_REG(cpu, Z80_BC, data);
1222
1223   data = (snapdata[SEM_OFFSET +  5] << 8) | snapdata[SEM_OFFSET +  4];
1224   LOAD_REG(cpu, Z80_DE, data);
1225
1226   data = (snapdata[SEM_OFFSET +  7] << 8) | snapdata[SEM_OFFSET +  6];
1227   LOAD_REG(cpu, Z80_HL, data);
1228
1229
1230   data = (snapdata[SEM_OFFSET +  9] << 8) | snapdata[SEM_OFFSET +  8];
1231   LOAD_REG(cpu, Z80_AF2, data);
1232
1233   data = (snapdata[SEM_OFFSET + 11] << 8) | snapdata[SEM_OFFSET + 10];
1234   LOAD_REG(cpu, Z80_BC2, data);
1235
1236   data = (snapdata[SEM_OFFSET + 13] << 8) | snapdata[SEM_OFFSET + 12];
1237   LOAD_REG(cpu, Z80_DE2, data);
1238
1239   data = (snapdata[SEM_OFFSET + 15] << 8) | snapdata[SEM_OFFSET + 14];
1240   LOAD_REG(cpu, Z80_HL2, data);
1241
1242
1243   data = (snapdata[SEM_OFFSET + 21] << 8) | snapdata[SEM_OFFSET + 20];
1244   LOAD_REG(cpu, Z80_IX, data);
1245
1246   data = (snapdata[SEM_OFFSET + 23] << 8) | snapdata[SEM_OFFSET + 22];
1247   LOAD_REG(cpu, Z80_IY, data);
1248
1249
1250   data = snapdata[SEM_OFFSET + 26];
1251   LOAD_REG(cpu, Z80_R, data);
1252
1253   data = snapdata[SEM_OFFSET + 24];
1254   LOAD_REG(cpu, Z80_I, data);
1255
1256
1257   data = (snapdata[SEM_OFFSET + 19] << 8) | snapdata[SEM_OFFSET + 18];
1258   LOAD_REG(cpu, Z80_SP, data);
1259
1260   data = (snapdata[SEM_OFFSET + 17] << 8) | snapdata[SEM_OFFSET + 16];
1261   LOAD_REG(cpu, Z80_PC, data);
1262
1263   data = snapdata[SEM_OFFSET + 32];
1264   LOAD_REG(cpu, Z80_IM, data);
1265
1266   data = snapdata[SEM_OFFSET + 28];
1267   LOAD_REG(cpu, Z80_IFF1, BIT(data, 0));
1268   data = snapdata[SEM_OFFSET + 30];
1269   LOAD_REG(cpu, Z80_IFF2, BIT(data, 0));
1270
1271   intr = BIT(snapdata[SEM_OFFSET + 30], 0) ? CLEAR_LINE : ASSERT_LINE;
1272   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
1273   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
1274
1275   /* Memory dump */
1276   logerror("Loading %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
1277   for (i = 0; i < 3*SPECTRUM_BANK; i++)
1278      space.write_byte(BASE_RAM + i, snapdata[SEM_SIGNATURE + i]);
1279
1280   /* Set border color */
1281   data = (space.read_byte(0x5c48) >> 3) & 0x07; // Get the current border color from BORDCR system variable.
1282   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
1283   spectrum_border_update(machine, data);
1284   logerror("Border color:%02X\n", data);
1285
1286   spectrum_page_basicrom(machine);
1287
1288   //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
1289
1290/* TODO: Decode the optional POKE bank at the end of the image */
1291
1292}
1293
1294/*******************************************************************
1295 *
1296 *      Load a .SIT file.
1297 *
1298 *      .SIT files were produced by a spanish emulator called Sinclair
1299 *      written by Pedro M. R. Salas.
1300 *
1301 *      http://www.ugr.es/~pedrom/sinclair.htm
1302 *
1303 *      The files are always 65564 bytes long and store both ROM and RAM.
1304 *
1305 *      Offset  Size    Description (all registers stored with LSB first)
1306 *      ------- ------- -------------------------------------------------
1307 *      0       2       BC
1308 *      2       2       DE
1309 *      4       2       HL
1310 *      6       2       AF
1311 *      8       2       IX
1312 *      10      2       IY
1313 *      12      2       SP
1314 *      14      2       PC
1315 *      16      1       R
1316 *      17      1       I
1317 *      18      2       BC'
1318 *      20      2       DE'
1319 *      22      2       HL'
1320 *      24      2       AF'
1321 *      26      1       Interrupt mode (0=IM0/1=IM1/2=IM2)
1322 *      27      1       Border color
1323 *      28      16384   ROM dump
1324 *      16412   49152   RAM dump
1325 *
1326 *******************************************************************/
1327void spectrum_setup_sit(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
1328{
1329   int i;
1330   UINT8 intr;
1331   UINT16 data;
1332   spectrum_state *state = machine.driver_data<spectrum_state>();
1333   device_t *cpu = machine.device("maincpu");
1334   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1335
1336   data = (snapdata[SIT_OFFSET +  7] << 8) | snapdata[SIT_OFFSET +  6];
1337   LOAD_REG(cpu, Z80_AF, data);
1338
1339   data = (snapdata[SIT_OFFSET +  1] << 8) | snapdata[SIT_OFFSET +  0];
1340   LOAD_REG(cpu, Z80_BC, data);
1341
1342   data = (snapdata[SIT_OFFSET +  3] << 8) | snapdata[SIT_OFFSET +  2];
1343   LOAD_REG(cpu, Z80_DE, data);
1344
1345   data = (snapdata[SIT_OFFSET +  5] << 8) | snapdata[SIT_OFFSET +  4];
1346   LOAD_REG(cpu, Z80_HL, data);
1347
1348
1349   data = (snapdata[SIT_OFFSET + 25] << 8) | snapdata[SIT_OFFSET + 24];
1350   LOAD_REG(cpu, Z80_AF2, data);
1351
1352   data = (snapdata[SIT_OFFSET + 19] << 8) | snapdata[SIT_OFFSET + 18];
1353   LOAD_REG(cpu, Z80_BC2, data);
1354
1355   data = (snapdata[SIT_OFFSET + 21] << 8) | snapdata[SIT_OFFSET + 20];
1356   LOAD_REG(cpu, Z80_DE2, data);
1357
1358   data = (snapdata[SIT_OFFSET + 23] << 8) | snapdata[SIT_OFFSET + 22];
1359   LOAD_REG(cpu, Z80_HL2, data);
1360
1361
1362   data = (snapdata[SIT_OFFSET +  9] << 8) | snapdata[SIT_OFFSET +  8];
1363   LOAD_REG(cpu, Z80_IX, data);
1364
1365   data = (snapdata[SIT_OFFSET + 11] << 8) | snapdata[SIT_OFFSET + 10];
1366   LOAD_REG(cpu, Z80_IY, data);
1367
1368
1369   data = snapdata[SIT_OFFSET + 16];
1370   LOAD_REG(cpu, Z80_R, data);
1371
1372   data = snapdata[SIT_OFFSET + 17];
1373   LOAD_REG(cpu, Z80_I, data);
1374
1375
1376   data = (snapdata[SIT_OFFSET + 13] << 8) | snapdata[SIT_OFFSET + 12];
1377   LOAD_REG(cpu, Z80_SP, data);
1378
1379   data = (snapdata[SIT_OFFSET + 15] << 8) | snapdata[SIT_OFFSET + 14];
1380   LOAD_REG(cpu, Z80_PC, data);
1381
1382   data = snapdata[SIT_OFFSET + 26];
1383   LOAD_REG(cpu, Z80_IM, data);
1384
1385   data = 0x01; // .SIT snapshots don't specify whether interrupts are enabled or not, so I assume they are.
1386   LOAD_REG(cpu, Z80_IFF1, data);
1387   LOAD_REG(cpu, Z80_IFF2, data);
1388
1389   intr = data ? CLEAR_LINE : ASSERT_LINE;
1390   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
1391   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
1392
1393   /* Memory dump */
1394   logerror("Skipping the 16K ROM dump at offset:%04X\n", SIT_OFFSET + 28);
1395   logerror("Loading %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
1396   for (i = 0; i < 3*SPECTRUM_BANK; i++)
1397      space.write_byte(BASE_RAM + i, snapdata[SIT_HDR + SPECTRUM_BANK + i]);
1398
1399   /* Set border color */
1400   data = snapdata[SIT_OFFSET + 27] & 0x07;
1401   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
1402   spectrum_border_update(machine, data);
1403   logerror("Border color:%02X\n", data);
1404
1405   spectrum_page_basicrom(machine);
1406
1407   //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
1408}
1409
1410/*******************************************************************
1411 *
1412 *      Load a .ZX file.
1413 *
1414 *      .ZX files were produced by the Amiga emulator called KGB
1415 *
1416 *      The files are usually 49486 bytes and store at the beginning
1417 *      of the file the last 132 bytes of the ROM.
1418 *
1419 *      Offset  Size    Description (all registers stored with MSB first)
1420 *      ------- ------- -------------------------------------------------
1421 *      0       132     Last 132 bytes of ROM dump
1422 *      132     49152   RAM dump
1423 *      49284   132     0x00 (reserved for future use)
1424 *      49416   10      Various KGB settings
1425 *      49426   1       IFF1/2: (0=DI/1=EI)
1426 *      49427   2       Reserved (must be 0x0003)
1427 *      49429   1       KGB ColorMode (0=BW/1=Color)
1428 *      49430   4       0x00 (reserved for future use)
1429 *      49434   2       BC
1430 *      49436   2       BC'
1431 *      49438   2       DE
1432 *      49440   2       DE'
1433 *      49442   2       HL
1434 *      49444   2       HL'
1435 *      49446   2       IX
1436 *      49448   2       IY
1437 *      49450   1       I
1438 *      49451   1       R
1439 *      49452   3       0x00 (reserved for future use)
1440 *      49455   1       A'
1441 *      49456   1       0x00 (reserved for future use)
1442 *      49457   1       A
1443 *      49458   1       0x00 (reserved for future use)
1444 *      49459   1       F'
1445 *      49460   1       0x00 (reserved for future use)
1446 *      49461   1       F
1447 *      49462   2       0x00 (reserved for future use)
1448 *      49464   2       PC
1449 *      49466   2       0x00 (reserved for future use)
1450 *      49468   2       SP
1451 *      49470   2       KGB Soundmode (0=Simple/1=Pitch/2=RomOnly)
1452 *      49472   2       KGB HaltMode (0=NoHalt/1=Halt)
1453 *      49474   2       Interrupt mode (-1=IM0/0=IM1/1=IM2)
1454 *      49476   10      0x00 (reserved for future use)
1455 *
1456 *******************************************************************/
1457void spectrum_setup_zx(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
1458{
1459   int i;
1460   UINT8 intr;
1461   UINT16 data, mode;
1462   spectrum_state *state = machine.driver_data<spectrum_state>();
1463   device_t *cpu = machine.device("maincpu");
1464   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1465
1466   logerror("Skipping last 132 bytes of the 16K ROM dump at offset:0000\n");
1467
1468   data = (snapdata[ZX_OFFSET + 173] << 8) | snapdata[ZX_OFFSET + 177];
1469   LOAD_REG(cpu, Z80_AF, data);
1470
1471   data = (snapdata[ZX_OFFSET + 150] << 8) | snapdata[ZX_OFFSET + 151];
1472   LOAD_REG(cpu, Z80_BC, data);
1473
1474   data = (snapdata[ZX_OFFSET + 154] << 8) | snapdata[ZX_OFFSET + 155];
1475   LOAD_REG(cpu, Z80_DE, data);
1476
1477   data = (snapdata[ZX_OFFSET + 158] << 8) | snapdata[ZX_OFFSET + 159];
1478   LOAD_REG(cpu, Z80_HL, data);
1479
1480
1481   data = (snapdata[ZX_OFFSET + 171] << 8) | snapdata[ZX_OFFSET + 175];
1482   LOAD_REG(cpu, Z80_AF2, data);
1483
1484   data = (snapdata[ZX_OFFSET + 152] << 8) | snapdata[ZX_OFFSET + 153];
1485   LOAD_REG(cpu, Z80_BC2, data);
1486
1487   data = (snapdata[ZX_OFFSET + 156] << 8) | snapdata[ZX_OFFSET + 157];
1488   LOAD_REG(cpu, Z80_DE2, data);
1489
1490   data = (snapdata[ZX_OFFSET + 160] << 8) | snapdata[ZX_OFFSET + 161];
1491   LOAD_REG(cpu, Z80_HL2, data);
1492
1493
1494   data = (snapdata[ZX_OFFSET + 162] << 8) | snapdata[ZX_OFFSET + 163];
1495   LOAD_REG(cpu, Z80_IX, data);
1496
1497   data = (snapdata[ZX_OFFSET + 164] << 8) | snapdata[ZX_OFFSET + 165];
1498   LOAD_REG(cpu, Z80_IY, data);
1499
1500
1501   data = snapdata[ZX_OFFSET + 167];
1502   LOAD_REG(cpu, Z80_R, data);
1503
1504   data = snapdata[ZX_OFFSET + 166];
1505   LOAD_REG(cpu, Z80_I, data);
1506
1507
1508   data = (snapdata[ZX_OFFSET + 184] << 8) | snapdata[ZX_OFFSET + 185];
1509   LOAD_REG(cpu, Z80_SP, data);
1510
1511   data = (snapdata[ZX_OFFSET + 180] << 8) | snapdata[ZX_OFFSET + 181];
1512   LOAD_REG(cpu, Z80_PC, data);
1513
1514   mode = (snapdata[ZX_OFFSET + 190] << 8) | snapdata[ZX_OFFSET + 191];
1515   switch (mode)
1516   {
1517      case 0xffff:
1518      LOAD_REG(cpu, Z80_IM, (UINT64)0);
1519      break;
1520      case 0x00:
1521      LOAD_REG(cpu, Z80_IM, 1);
1522      break;
1523      case 0x01:
1524      LOAD_REG(cpu, Z80_IM, 2);
1525      break;
1526      default:
1527      logerror("Invalid IM:%04X\n", mode);
1528   }
1529
1530   data = BIT(snapdata[ZX_OFFSET + 142], 0);
1531   LOAD_REG(cpu, Z80_IFF1, data);
1532   LOAD_REG(cpu, Z80_IFF2, data);
1533
1534   intr = BIT(snapdata[ZX_OFFSET + 142], 0) ? CLEAR_LINE : ASSERT_LINE;
1535   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
1536   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
1537
1538   /* Memory dump */
1539   logerror("Loading %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
1540   for (i = 0; i < 3*SPECTRUM_BANK; i++)
1541      space.write_byte(BASE_RAM + i, snapdata[132 + i]);
1542
1543   /* Set border color */
1544   data = (space.read_byte(0x5c48) >> 3) & 0x07; // Get the current border color from BORDCR system variable.
1545   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
1546   spectrum_border_update(machine, data);
1547   logerror("Border color:%02X\n", data);
1548
1549   spectrum_page_basicrom(machine);
1550
1551   //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
1552}
1553
1554/*******************************************************************
1555 *
1556 *      Load a .SNP file.
1557 *
1558 *      .SNP files were produced by a polish emulator called Nuclear ZX
1559 *      written by Radovan Garabik and Lubomir Salanci.
1560 *
1561 *      http://korpus.juls.savba.sk/~garabik/old/zx.html
1562 *
1563 *      The files are always 49183 bytes long.
1564 *
1565 *      Offset  Size    Description (all registers stored with LSB first)
1566 *      ------- ------- -------------------------------------------------
1567 *      0       49152   RAM dump
1568 *      49152   2       AF
1569 *      49154   1       Border color
1570 *      49155   1       0x00 (reserved for future use)
1571 *      49156   2       BC
1572 *      49158   2       DE
1573 *      49160   2       HL
1574 *      49162   2       PC
1575 *      49164   2       SP
1576 *      49166   2       IX
1577 *      49168   2       IY
1578 *      49170   1       0x00 (reserved for IFF2 but not implemented)
1579 *      49171   1       IFF1 (0=DI/other=EI)
1580 *      49172   1       Interrupt mode (0=IM0/1=IM1/2=IM2)
1581 *      49173   1       R
1582 *      49174   1       I
1583 *      49175   2       AF'
1584 *      49177   2       BC'
1585 *      49179   2       DE'
1586 *      49181   2       HL'
1587 *
1588 *******************************************************************/
1589void spectrum_setup_snp(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
1590{
1591   int i;
1592   UINT8 intr;
1593   UINT16 data;
1594   spectrum_state *state = machine.driver_data<spectrum_state>();
1595   device_t *cpu = machine.device("maincpu");
1596   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1597
1598   data = (snapdata[SNP_OFFSET +  1] << 8) | snapdata[SNP_OFFSET +  0];
1599   LOAD_REG(cpu, Z80_AF, data);
1600
1601   data = (snapdata[SNP_OFFSET +  5] << 8) | snapdata[SNP_OFFSET +  4];
1602   LOAD_REG(cpu, Z80_BC, data);
1603
1604   data = (snapdata[SNP_OFFSET +  7] << 8) | snapdata[SNP_OFFSET +  6];
1605   LOAD_REG(cpu, Z80_DE, data);
1606
1607   data = (snapdata[SNP_OFFSET +  9] << 8) | snapdata[SNP_OFFSET +  8];
1608   LOAD_REG(cpu, Z80_HL, data);
1609
1610
1611   data = (snapdata[SNP_OFFSET + 24] << 8) | snapdata[SNP_OFFSET + 23];
1612   LOAD_REG(cpu, Z80_AF2, data);
1613
1614   data = (snapdata[SNP_OFFSET + 26] << 8) | snapdata[SNP_OFFSET + 25];
1615   LOAD_REG(cpu, Z80_BC2, data);
1616
1617   data = (snapdata[SNP_OFFSET + 28] << 8) | snapdata[SNP_OFFSET + 27];
1618   LOAD_REG(cpu, Z80_DE2, data);
1619
1620   data = (snapdata[SNP_OFFSET + 30] << 8) | snapdata[SNP_OFFSET + 29];
1621   LOAD_REG(cpu, Z80_HL2, data);
1622
1623
1624   data = (snapdata[SNP_OFFSET + 15] << 8) | snapdata[SNP_OFFSET + 14];
1625   LOAD_REG(cpu, Z80_IX, data);
1626
1627   data = (snapdata[SNP_OFFSET + 17] << 8) | snapdata[SNP_OFFSET + 16];
1628   LOAD_REG(cpu, Z80_IY, data);
1629
1630
1631   data = snapdata[SNP_OFFSET + 21];
1632   LOAD_REG(cpu, Z80_R, data);
1633
1634   data = snapdata[SNP_OFFSET + 22];
1635   LOAD_REG(cpu, Z80_I, data);
1636
1637
1638   data = (snapdata[SNP_OFFSET + 13] << 8) | snapdata[SNP_OFFSET + 12];
1639   LOAD_REG(cpu, Z80_SP, data);
1640
1641   data = (snapdata[SNP_OFFSET + 11] << 8) | snapdata[SNP_OFFSET + 10];
1642   LOAD_REG(cpu, Z80_PC, data);
1643
1644
1645   data = snapdata[SNP_OFFSET + 20] & 0x03;
1646   LOAD_REG(cpu, Z80_IM, data);
1647
1648   data = BIT(snapdata[SNP_OFFSET + 19], 0);
1649   LOAD_REG(cpu, Z80_IFF1, data);
1650   LOAD_REG(cpu, Z80_IFF2, data);
1651
1652   intr = BIT(snapdata[SNP_OFFSET + 19], 0) ? CLEAR_LINE : ASSERT_LINE;
1653   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
1654   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
1655
1656   /* Memory dump */
1657   logerror("Loading %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
1658   for (i = 0; i < 3*SPECTRUM_BANK; i++)
1659      space.write_byte(BASE_RAM + i, snapdata[i]);
1660
1661   /* Set border color */
1662   data = snapdata[SNP_OFFSET +  2] & 0x07;
1663   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
1664   spectrum_border_update(machine, data);
1665   logerror("Border color:%02X\n", data);
1666
1667   spectrum_page_basicrom(machine);
1668
1669   //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
1670}
1671
1672/*******************************************************************
1673 *
1674 *      Load a .SNX file.
1675 *
1676 *      .SNX files were produced by an Atari ST emulator called Specci
1677 *      written by Christian Gandler
1678 *
1679 *      http://cd.textfiles.com/crawlycrypt1/apps/misc/zx_sp207/
1680 *
1681 *      The header is an extension of the .SNA format and the RAM dump
1682 *      is compressed with a simple run-length algorithm.
1683 *
1684 *      Offset  Size    Description (all registers stored with LSB first
1685 *                      except when noted with *BE*)
1686 *      ------- ------- -------------------------------------------------
1687 *      0       4       "XSNA" (signature)
1688 *      4       2       Header length *BE*
1689 *      6       1       I
1690 *      7       2       HL'
1691 *      9       2       DE'
1692 *      11      2       BC'
1693 *      13      2       AF'
1694 *      15      2       HL
1695 *      17      2       DE
1696 *      19      2       BC
1697 *      21      2       IY
1698 *      23      2       IX
1699 *      25      1       IFF1/2: bit 0 contains IFF1, bit 2 contains IFF2 (0=DI/1=EI)
1700 *      26      1       R
1701 *      27      2       AF
1702 *      29      2       SP
1703 *      31      1       Interrupt Mode (0=IM0/1=IM1/2=IM2)
1704 *      32      1       Border color
1705 *      33      1       Specci settings: Interface 1 (0=no/1=yes)
1706 *      34      1       Specci settings: FLASH emulation (0=no/1=yes)
1707 *      35      1       Specci settings: Attributes emulation (0=no/1=yes)
1708 *      36      1       Specci settings: Bit 7 - Keyboard (0=QWERTY/1=QWERTZ)
1709 *                                       Bit 6 - ULA emulation (0=no/1=yes)
1710 *                                       Bit 0,1 - Joystick interface
1711 *                                            00 = Kempston
1712 *                                            01 = IF2 Left
1713 *                                            10 = IF2 Right
1714 *                                            11 = Cursor/AGF/Protek
1715 *      37      1       Specci settings: R register emulation (0=no/1=yes)
1716 *                                       Bit 7 - EAR bit (0=Issue 3/1=Issue 2)
1717 *      38      1       Specci settings: Interrupt frequency (0=50 Hz/1=100 Hz)
1718 *      39      1       Specci settings: RS232 redirection (0=RS232/1=Centronics)
1719 *      40      1       Specci settings: Sound emulation
1720 *                                       Bit 4,7 - Frequency (0..4) for mode 2
1721 *                                       Bit 0,3 - Mode (0=off/1=direct/2=interrupt)
1722 *      41      1       Specci settings: Border emulation (0=off/1=direct/2=interrupt)
1723 *      42      1       Specci settings: IM2 hardware vector (0..255)
1724 *      43      ?????   RAM dump
1725 *
1726 *      PC is stored on stack.
1727 *
1728 *      The RAM dump is divided into short or long datablocks:
1729 *      if the block is composed of the same byte, it is replaced by
1730 *      a compressed version. The format of the various blocks follows:
1731 *
1732 *      Uncompressed short block
1733 *      ------------------------
1734 *      Offset  Size    Description
1735 *      ------- ------- -------------------------------------------------
1736 *      0       1       Marker byte. Values between 0xe0 and 0xef.
1737 *                      Low nibble is (block length - 1).
1738 *      1       ?????   Data block
1739 *
1740 *      Compressed short block
1741 *      ----------------------
1742 *      Offset  Size    Description
1743 *      ------- ------- -------------------------------------------------
1744 *      0       1       Marker byte. Values between 0xf0 and 0xff.
1745 *                      Low nibble is (block length - 1).
1746 *      1       1       Filler byte. This byte is repeated for the whole
1747 *                      length of the block.
1748 *
1749 *      Uncompressed long block
1750 *      -----------------------
1751 *      Offset  Size    Description
1752 *      ------- ------- -------------------------------------------------
1753 *      0       2       Block length in big endian format.
1754 *                      Values between 0x0000 and 0xdfff.
1755 *      2       1       Uncompressed block flag: 0xff.
1756 *      3       ?????   Data block
1757 *
1758 *      Compressed long block
1759 *      ---------------------
1760 *      Offset  Size    Description
1761 *      ------- ------- -------------------------------------------------
1762 *      0       2       Block length in big endian format.
1763 *                      Values between 0x0000 and 0xdfff.
1764 *      2       1       Compressed block flag: 0x00.
1765 *      3       1       Filler byte. This byte is repeated for the whole
1766 *                      length of the block.
1767 *
1768 *******************************************************************/
1769static void spectrum_snx_decompress_block(running_machine &machine, UINT8 *source, UINT16 dest, UINT16 size)
1770{
1771   UINT8 counthi, countlo, compress, fill;
1772   UINT16 block = 0, count, i, j, numbytes;
1773   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1774
1775   i = SNX_HDR - 1;
1776   numbytes = 0;
1777
1778   while (numbytes < size)
1779   {
1780      counthi = source[++i];
1781      if (counthi >= 0xe0)
1782      {
1783         count = (counthi & 0x0f) + 1;     // Short block
1784         if ((counthi & 0xf0) == 0xf0)
1785            compress = SNX_COMPRESSED;
1786         else
1787            compress = SNX_UNCOMPRESSED;
1788         logerror("Block:%05d  Type:Short  Compr:%s  Offset:%04X  Len:%04X  ", block++, compress == SNX_COMPRESSED ? "Y" : "N", i-1, count);
1789      }
1790      else
1791      {
1792         countlo = source[++i];
1793         count = (counthi << 8) | countlo; // Long block
1794         compress = source[++i];
1795         logerror("Block:%05d  Type:Long   Compr:%s  Offset:%04X  Len:%04X  ", block++, compress == SNX_COMPRESSED ? "Y" : "N", i-3, count);
1796      }
1797
1798      if (compress == SNX_COMPRESSED)
1799      {
1800         fill = source[++i];
1801         logerror("Dest:%04X  Filler:%02X\n", BASE_RAM + numbytes, fill);
1802         for(j = 0; j < count; j++)
1803            space.write_byte(BASE_RAM + numbytes + j, fill);
1804         numbytes += count;
1805      }
1806      else
1807      {
1808         logerror("Dest:%04X\n", BASE_RAM + numbytes);
1809         j = 0;
1810         while (j < count)
1811            space.write_byte(BASE_RAM + numbytes + j++, source[++i]);
1812         numbytes += count;
1813      }
1814   }
1815}
1816
1817void spectrum_setup_snx(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
1818{
1819   UINT8 intr;
1820   UINT16 data, addr;
1821   spectrum_state *state = machine.driver_data<spectrum_state>();
1822   device_t *cpu = machine.device("maincpu");
1823   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1824
1825   data = (snapdata[SNX_OFFSET +  4] << 8) | snapdata[SNX_OFFSET +  5];
1826   if (data != 0x25)
1827      logerror("Corrupted header length: %02X instead of 0x25\n", data);
1828
1829   data = (snapdata[SNX_OFFSET + 28] << 8) | snapdata[SNX_OFFSET + 27];
1830   LOAD_REG(cpu, Z80_AF, data);
1831
1832   data = (snapdata[SNX_OFFSET + 20] << 8) | snapdata[SNX_OFFSET + 19];
1833   LOAD_REG(cpu, Z80_BC, data);
1834
1835   data = (snapdata[SNX_OFFSET + 18] << 8) | snapdata[SNX_OFFSET + 17];
1836   LOAD_REG(cpu, Z80_DE, data);
1837
1838   data = (snapdata[SNX_OFFSET + 16] << 8) | snapdata[SNX_OFFSET + 15];
1839   LOAD_REG(cpu, Z80_HL, data);
1840
1841
1842   data = (snapdata[SNX_OFFSET + 14] << 8) | snapdata[SNX_OFFSET + 13];
1843   LOAD_REG(cpu, Z80_AF2, data);
1844
1845   data = (snapdata[SNX_OFFSET + 12] << 8) | snapdata[SNX_OFFSET + 11];
1846   LOAD_REG(cpu, Z80_BC2, data);
1847
1848   data = (snapdata[SNX_OFFSET + 10] << 8) | snapdata[SNX_OFFSET +  9];
1849   LOAD_REG(cpu, Z80_DE2, data);
1850
1851   data = (snapdata[SNX_OFFSET +  8] << 8) | snapdata[SNX_OFFSET +  7];
1852   LOAD_REG(cpu, Z80_HL2, data);
1853
1854
1855   data = (snapdata[SNX_OFFSET + 24] << 8) | snapdata[SNX_OFFSET + 23];
1856   LOAD_REG(cpu, Z80_IX, data);
1857
1858   data = (snapdata[SNX_OFFSET + 22] << 8) | snapdata[SNX_OFFSET + 21];
1859   LOAD_REG(cpu, Z80_IY, data);
1860
1861
1862   data = snapdata[SNX_OFFSET + 26];
1863   LOAD_REG(cpu, Z80_R, data);
1864
1865   data = snapdata[SNX_OFFSET +  6];
1866   LOAD_REG(cpu, Z80_I, data);
1867
1868
1869   data = (snapdata[SNX_OFFSET + 30] << 8) | snapdata[SNX_OFFSET + 29];
1870   LOAD_REG(cpu, Z80_SP, data);
1871
1872
1873   data = snapdata[SNX_OFFSET + 31] & 0x03;
1874   if (data == 3)
1875      data = 2;
1876   LOAD_REG(cpu, Z80_IM, data);
1877
1878   data = snapdata[SNX_OFFSET + 25];
1879   LOAD_REG(cpu, Z80_IFF1, BIT(data, 0));
1880   LOAD_REG(cpu, Z80_IFF2, BIT(data, 2));
1881
1882   intr = BIT(data, 0) ? CLEAR_LINE : ASSERT_LINE;
1883   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
1884   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
1885
1886   /* Memory dump */
1887   logerror("Uncompressing %04X bytes of RAM at %04X\n", 3*SPECTRUM_BANK, BASE_RAM);
1888   spectrum_snx_decompress_block(machine, snapdata, BASE_RAM, 3*SPECTRUM_BANK);
1889
1890   /* get pc from stack */
1891   addr = cpu->state().state_int(Z80_SP);
1892
1893   if (addr < BASE_RAM || addr > 4*SPECTRUM_BANK - 2)
1894      logerror("Corrupted SP out of range:%04X", addr);
1895   else
1896      logerror("Fetching PC from the stack at SP:%04X\n", addr);
1897
1898   LOAD_REG(cpu, Z80_PC, (space.read_byte(addr + 1) << 8) | space.read_byte(addr + 0));
1899
1900#if 0
1901   space.write_byte(addr + 0, 0); // It's been reported that zeroing these locations fixes the loading
1902   space.write_byte(addr + 1, 0); // of a few images that were snapshot at a "wrong" instant
1903#endif
1904
1905   addr += 2;
1906   logerror("Fixed the stack at SP:%04X\n", addr);
1907   cpu->state().set_state_int(Z80_SP, addr);
1908
1909   /* Set border color */
1910   data = snapdata[SNX_OFFSET + 32] & 0x07;
1911   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
1912   spectrum_border_update(machine, data);
1913   logerror("Border color:%02X\n", data);
1914
1915   spectrum_page_basicrom(machine);
1916
1917/* TODO: Enable/disable IF1 as per snapdata[SNX_OFFSET + 33] */
1918
1919/* TODO: Enable/disable joysticks as per snapdata[SNX_OFFSET + 36] */
1920
1921/* TODO: Enable selection of Issue 2/3 config switch as per snapdata[SNX_OFFSET + 37] */
1922
1923   //logerror("Snapshot loaded.\nExecution resuming at %s\n", cpu_get_reg_string(cpu, Z80_PC));
1924}
1925
1926/*******************************************************************
1927 *
1928 *      Load a .FRZ file.
1929 *
1930 *      .FRZ files were produced by the czech Amiga emulator CBSpeccy
1931 *      written by the CodeBusters. Kudos to Dmitriy Zhivilov and
1932 *      Ian Greenway for having reverse-engineered and shared the
1933 *      description of this format.
1934 *
1935 *      The original specs of this format were published on a
1936 *      russian electronics magazine.
1937 *
1938 *      The format is always 131114 bytes long and supports only
1939 *      Spectrum 128K images.
1940 *
1941 *      Offset  Size    Description (all registers stored with MSB first)
1942 *      ------- ------- -------------------------------------------------
1943 *      0       1       0x00 (reserved for future use)
1944 *      1       1       Port 0x7FFD data
1945 *      2       2       HL'
1946 *      4       2       HL
1947 *      6       2       DE'
1948 *      8       2       DE
1949 *      10      2       BC'
1950 *      12      2       BC
1951 *      14      2       AF'
1952 *      16      2       AF
1953 *      18      7       Emulation disk registers and T-states
1954 *      25      1       R
1955 *      26      2       PC
1956 *      28      2       SP
1957 *      30      1       I
1958 *      31      1       0xFF (reserved for future use)
1959 *      32      1       0x00 (reserved for future use)
1960 *      33      1       Interrupt mode (0=IM0/1=IM1/2=IM2)
1961 *      34      3       0x00 (reserved for future use)
1962 *      37      1       IFF1: bit 2 contains IFF1 (0=DI/1=EI)
1963 *      38      2       IY
1964 *      40      2       IX
1965 *      42      131072  RAM dump
1966 *
1967 *      The 8 16K banks are stored in the order 5, 2, 0, 1, 3, 4, 6, 7
1968 *
1969 *******************************************************************/
1970void spectrum_setup_frz(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
1971{
1972   int i, j;
1973   UINT8 intr;
1974   UINT16 addr, data;
1975   spectrum_state *state = machine.driver_data<spectrum_state>();
1976   device_t *cpu = machine.device("maincpu");
1977   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1978
1979   if (state->m_port_7ffd_data == -1)
1980   {
1981      logerror("Can't load 128K .FRZ file into 48K machine\n");
1982      return;
1983   }
1984
1985   data = (snapdata[FRZ_OFFSET + 16] << 8) | snapdata[FRZ_OFFSET + 17];
1986   LOAD_REG(cpu, Z80_AF, data);
1987
1988   data = (snapdata[FRZ_OFFSET + 12] << 8) | snapdata[FRZ_OFFSET + 13];
1989   LOAD_REG(cpu, Z80_BC, data);
1990
1991   data = (snapdata[FRZ_OFFSET +  8] << 8) | snapdata[FRZ_OFFSET +  9];
1992   LOAD_REG(cpu, Z80_DE, data);
1993
1994   data = (snapdata[FRZ_OFFSET +  4] << 8) | snapdata[FRZ_OFFSET +  5];
1995   LOAD_REG(cpu, Z80_HL, data);
1996
1997
1998   data = (snapdata[FRZ_OFFSET + 14] << 8) | snapdata[FRZ_OFFSET + 15];
1999   LOAD_REG(cpu, Z80_AF2, data);
2000
2001   data = (snapdata[FRZ_OFFSET + 10] << 8) | snapdata[FRZ_OFFSET + 11];
2002   LOAD_REG(cpu, Z80_BC2, data);
2003
2004   data = (snapdata[FRZ_OFFSET +  6] << 8) | snapdata[FRZ_OFFSET +  7];
2005   LOAD_REG(cpu, Z80_DE2, data);
2006
2007   data = (snapdata[FRZ_OFFSET +  2] << 8) | snapdata[FRZ_OFFSET +  3];
2008   LOAD_REG(cpu, Z80_HL2, data);
2009
2010
2011   data = (snapdata[FRZ_OFFSET + 40] << 8) | snapdata[FRZ_OFFSET + 41];
2012   LOAD_REG(cpu, Z80_IX, data);
2013
2014   data = (snapdata[FRZ_OFFSET + 38] << 8) | snapdata[FRZ_OFFSET + 39];
2015   LOAD_REG(cpu, Z80_IY, data);
2016
2017
2018   data = snapdata[FRZ_OFFSET + 25];
2019   LOAD_REG(cpu, Z80_R, data);
2020
2021   data = snapdata[FRZ_OFFSET + 30];
2022   LOAD_REG(cpu, Z80_I, data);
2023
2024
2025   data = (snapdata[FRZ_OFFSET + 28] << 8) | snapdata[FRZ_OFFSET + 29];
2026   LOAD_REG(cpu, Z80_SP, data);
2027
2028   data = (snapdata[FRZ_OFFSET + 26] << 8) | snapdata[FRZ_OFFSET + 27];
2029   LOAD_REG(cpu, Z80_PC, data);
2030
2031
2032   data = snapdata[FRZ_OFFSET + 33];
2033   LOAD_REG(cpu, Z80_IM, data);
2034
2035   data = snapdata[FRZ_OFFSET + 37];
2036   LOAD_REG(cpu, Z80_IFF1, BIT(data, 2));
2037   LOAD_REG(cpu, Z80_IFF2, BIT(data, 2));
2038
2039   intr = BIT(data, 2) ? CLEAR_LINE : ASSERT_LINE;
2040   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, intr);
2041   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
2042
2043   /* Memory dump */
2044   addr = 0;
2045   static const UINT8 banks[] = { 5, 2, 0, 1, 3, 4, 6, 7 };
2046   logerror("Loading %05X bytes of RAM at %04X\n", 8*SPECTRUM_BANK, BASE_RAM);
2047   for (i = 0; i < 8; i++)
2048   {
2049      switch (banks[i])
2050      {
2051         case 5: addr = SPECTRUM_BANK;
2052               break;
2053         case 2: addr = 2*SPECTRUM_BANK;
2054               break;
2055         case 0:
2056         case 1:
2057         case 3:
2058         case 4:
2059         case 6:
2060         case 7: addr = 3*SPECTRUM_BANK;
2061               state->m_port_7ffd_data &= 0xf8;
2062               state->m_port_7ffd_data += banks[i];
2063               spectrum_update_paging(machine);
2064               break;
2065      };
2066      logerror("Loading bank %d from offset:%05X\n", banks[i], FRZ_HDR + i*SPECTRUM_BANK);
2067      for (j = 0; j < SPECTRUM_BANK; j++)
2068         space.write_byte(j + addr, snapdata[j + FRZ_HDR + i*SPECTRUM_BANK]);
2069   }
2070   state->m_port_7ffd_data = snapdata[FRZ_OFFSET +  1];
2071   logerror ("Port 7FFD:%02X\n", state->m_port_7ffd_data);
2072   logerror ("Paging bank:%d\n", state->m_port_7ffd_data & 0x07);
2073   spectrum_update_paging(machine);
2074
2075   /* Set border color */
2076   data = (space.read_byte(0x5c48) >> 3) & 0x07; // Get the current border color from BORDCR system variable.
2077   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
2078   spectrum_border_update(machine, data);
2079   logerror("Border color:%02X\n", data);
2080
2081   //logerror("Snapshot loaded.\nExecution resuming at bank:%d %s\n", state->m_port_7ffd_data & 0x07, cpu_get_reg_string(cpu, Z80_PC));
2082}
2083
2084static void spectrum_z80_decompress_block(running_machine &machine,UINT8 *source, UINT16 dest, UINT16 size)
2085{
2086   UINT8 ch;
2087   int i;
2088   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
2089
2090   do
2091   {
2092      /* get byte */
2093      ch = source[0];
2094
2095      /* either start 0f 0x0ed, 0x0ed, xx yy or single 0x0ed */
2096      if (ch == 0x0ed)
2097      {
2098         if (source[1] == 0x0ed)
2099         {
2100            /* 0x0ed, 0x0ed, xx yy - repetition */
2101            UINT8 count;
2102            UINT8 data;
2103
2104            count = source[2];
2105
2106            if (count == 0)
2107               return;
2108
2109            data = source[3];
2110
2111            source += 4;
2112
2113            if (count > size)
2114               count = size;
2115
2116            size -= count;
2117
2118            for (i = 0; i < count; i++)
2119            {
2120               space.write_byte(dest, data);
2121               dest++;
2122            }
2123         }
2124         else
2125         {
2126            /* single 0x0ed */
2127            space.write_byte(dest, ch);
2128            dest++;
2129            source++;
2130            size--;
2131         }
2132      }
2133      else
2134      {
2135         /* not 0x0ed */
2136         space.write_byte(dest, ch);
2137         dest++;
2138         source++;
2139         size--;
2140      }
2141   }
2142   while (size > 0);
2143}
2144
2145static SPECTRUM_Z80_SNAPSHOT_TYPE spectrum_identify_z80 (UINT8 *snapdata, UINT32 snapsize)
2146{
2147   UINT8 lo, hi, data;
2148
2149   if (snapsize < 30)
2150      return SPECTRUM_Z80_SNAPSHOT_INVALID;   /* Invalid file */
2151
2152   lo = snapdata[6] & 0x0ff;
2153   hi = snapdata[7] & 0x0ff;
2154   if (hi || lo)
2155      return SPECTRUM_Z80_SNAPSHOT_48K_OLD;   /* V1.45 - 48K only */
2156
2157   lo = snapdata[30] & 0x0ff;
2158   hi = snapdata[31] & 0x0ff;
2159   data = snapdata[34] & 0x0ff;            /* Hardware mode */
2160
2161   if ((hi == 0) && (lo == 23))
2162   {                       /* V2.01 */                         /* V2.01 format */
2163      switch (data)
2164      {
2165         case 0:
2166         case 1: return SPECTRUM_Z80_SNAPSHOT_48K;
2167         case 2: return SPECTRUM_Z80_SNAPSHOT_SAMRAM;
2168         case 3:
2169         case 4: return SPECTRUM_Z80_SNAPSHOT_128K;
2170         case 128: return SPECTRUM_Z80_SNAPSHOT_TS2068;
2171      }
2172   }
2173
2174   if ((hi == 0) && (lo == 54))
2175   {                       /* V3.0x */                         /* V2.01 format */
2176      switch (data)
2177      {
2178         case 0:
2179         case 1:
2180         case 3: return SPECTRUM_Z80_SNAPSHOT_48K;
2181         case 2: return SPECTRUM_Z80_SNAPSHOT_SAMRAM;
2182         case 4:
2183         case 5:
2184         case 6: return SPECTRUM_Z80_SNAPSHOT_128K;
2185         case 128: return SPECTRUM_Z80_SNAPSHOT_TS2068;
2186      }
2187   }
2188
2189   return SPECTRUM_Z80_SNAPSHOT_INVALID;
2190}
2191
2192/* now supports 48k & 128k .Z80 files */
2193void spectrum_setup_z80(running_machine &machine, UINT8 *snapdata, UINT32 snapsize)
2194{
2195   spectrum_state *state = machine.driver_data<spectrum_state>();
2196   int i;
2197   UINT8 lo, hi, data;
2198   SPECTRUM_Z80_SNAPSHOT_TYPE z80_type;
2199   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
2200
2201   z80_type = spectrum_identify_z80(snapdata, snapsize);
2202
2203   switch (z80_type)
2204   {
2205      case SPECTRUM_Z80_SNAPSHOT_INVALID:
2206            logerror("Invalid .Z80 file\n");
2207            return;
2208      case SPECTRUM_Z80_SNAPSHOT_48K_OLD:
2209      case SPECTRUM_Z80_SNAPSHOT_48K:
2210            logerror("48K .Z80 file\n");
2211            if (!strcmp(machine.system().name,"ts2068"))
2212               logerror("48K .Z80 file in TS2068\n");
2213            break;
2214      case SPECTRUM_Z80_SNAPSHOT_128K:
2215            logerror("128K .Z80 file\n");
2216            if (state->m_port_7ffd_data == -1)
2217            {
2218               logerror("Not a 48K .Z80 file\n");
2219               return;
2220            }
2221            if (!strcmp(machine.system().name,"ts2068"))
2222            {
2223               logerror("Not a TS2068 .Z80 file\n");
2224               return;
2225            }
2226            break;
2227      case SPECTRUM_Z80_SNAPSHOT_TS2068:
2228            logerror("TS2068 .Z80 file\n");
2229            if (strcmp(machine.system().name,"ts2068"))
2230               logerror("Not a TS2068 machine\n");
2231            break;
2232      case SPECTRUM_Z80_SNAPSHOT_SAMRAM:
2233            logerror("Hardware not supported - .Z80 file\n");
2234            return;
2235   }
2236
2237   /* AF */
2238   hi = snapdata[0] & 0x0ff;
2239   lo = snapdata[1] & 0x0ff;
2240   machine.device("maincpu")->state().set_state_int(Z80_AF, (hi << 8) | lo);
2241   /* BC */
2242   lo = snapdata[2] & 0x0ff;
2243   hi = snapdata[3] & 0x0ff;
2244   machine.device("maincpu")->state().set_state_int(Z80_BC, (hi << 8) | lo);
2245   /* HL */
2246   lo = snapdata[4] & 0x0ff;
2247   hi = snapdata[5] & 0x0ff;
2248   machine.device("maincpu")->state().set_state_int(Z80_HL, (hi << 8) | lo);
2249
2250   /* SP */
2251   lo = snapdata[8] & 0x0ff;
2252   hi = snapdata[9] & 0x0ff;
2253   machine.device("maincpu")->state().set_state_int(Z80_SP, (hi << 8) | lo);
2254
2255   /* I */
2256   machine.device("maincpu")->state().set_state_int(Z80_I, (snapdata[10] & 0x0ff));
2257
2258   /* R */
2259   data = (snapdata[11] & 0x07f) | ((snapdata[12] & 0x01) << 7);
2260   machine.device("maincpu")->state().set_state_int(Z80_R, data);
2261
2262   /* Set border color */
2263   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | ((snapdata[12] & 0x0e) >> 1);
2264   spectrum_border_update(machine, (snapdata[12] & 0x0e) >> 1);
2265
2266   lo = snapdata[13] & 0x0ff;
2267   hi = snapdata[14] & 0x0ff;
2268   machine.device("maincpu")->state().set_state_int(Z80_DE, (hi << 8) | lo);
2269
2270   lo = snapdata[15] & 0x0ff;
2271   hi = snapdata[16] & 0x0ff;
2272   machine.device("maincpu")->state().set_state_int(Z80_BC2, (hi << 8) | lo);
2273
2274   lo = snapdata[17] & 0x0ff;
2275   hi = snapdata[18] & 0x0ff;
2276   machine.device("maincpu")->state().set_state_int(Z80_DE2, (hi << 8) | lo);
2277
2278   lo = snapdata[19] & 0x0ff;
2279   hi = snapdata[20] & 0x0ff;
2280   machine.device("maincpu")->state().set_state_int(Z80_HL2, (hi << 8) | lo);
2281
2282   hi = snapdata[21] & 0x0ff;
2283   lo = snapdata[22] & 0x0ff;
2284   machine.device("maincpu")->state().set_state_int(Z80_AF2, (hi << 8) | lo);
2285
2286   lo = snapdata[23] & 0x0ff;
2287   hi = snapdata[24] & 0x0ff;
2288   machine.device("maincpu")->state().set_state_int(Z80_IY, (hi << 8) | lo);
2289
2290   lo = snapdata[25] & 0x0ff;
2291   hi = snapdata[26] & 0x0ff;
2292   machine.device("maincpu")->state().set_state_int(Z80_IX, (hi << 8) | lo);
2293
2294   /* Interrupt Flip/Flop */
2295   if (snapdata[27] == 0)
2296   {
2297      machine.device("maincpu")->state().set_state_int(Z80_IFF1, (UINT64)0);
2298      /* machine.device("maincpu")->state().set_state_int(Z80_IRQ_STATE, 0); */
2299   }
2300   else
2301   {
2302      machine.device("maincpu")->state().set_state_int(Z80_IFF1, 1);
2303      /* machine.device("maincpu")->state().set_state_int(Z80_IRQ_STATE, 1); */
2304   }
2305
2306   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
2307//  machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, data);
2308   machine.device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
2309
2310   /* IFF2 */
2311   if (snapdata[28] != 0)
2312   {
2313      data = 1;
2314   }
2315   else
2316   {
2317      data = 0;
2318   }
2319   machine.device("maincpu")->state().set_state_int(Z80_IFF2, data);
2320
2321   /* Interrupt Mode */
2322   machine.device("maincpu")->state().set_state_int(Z80_IM, (snapdata[29] & 0x03));
2323
2324   if (z80_type == SPECTRUM_Z80_SNAPSHOT_48K_OLD)
2325   {
2326      lo = snapdata[6] & 0x0ff;
2327      hi = snapdata[7] & 0x0ff;
2328      machine.device("maincpu")->state().set_state_int(Z80_PC, (hi << 8) | lo);
2329
2330      spectrum_page_basicrom(machine);
2331
2332      if ((snapdata[12] & 0x020) == 0)
2333      {
2334         logerror("Not compressed\n");   /* not compressed */
2335         for (i = 0; i < 49152; i++)
2336            space.write_byte(i + 16384, snapdata[30 + i]);
2337      }
2338      else
2339      {
2340         logerror("Compressed\n");   /* compressed */
2341         spectrum_z80_decompress_block(machine, snapdata + 30, 16384, 49152);
2342      }
2343   }
2344   else
2345   {
2346      UINT8 *pSource;
2347      int header_size;
2348
2349      header_size = 30 + 2 + ((snapdata[30] & 0x0ff) | ((snapdata[31] & 0x0ff) << 8));
2350
2351      lo = snapdata[32] & 0x0ff;
2352      hi = snapdata[33] & 0x0ff;
2353      machine.device("maincpu")->state().set_state_int(Z80_PC, (hi << 8) | lo);
2354
2355      if ((z80_type == SPECTRUM_Z80_SNAPSHOT_128K) || ((z80_type == SPECTRUM_Z80_SNAPSHOT_TS2068) && !strcmp(machine.system().name,"ts2068")))
2356      {
2357         device_t *ay8912 = machine.device("ay8912");
2358
2359         /* Only set up sound registers for 128K machine or TS2068! */
2360         for (i = 0; i < 16; i++)
2361         {
2362            ay8910_address_w(ay8912, state->generic_space(), 0, i);
2363            ay8910_data_w(ay8912, state->generic_space(), 0, snapdata[39 + i]);
2364         }
2365         ay8910_address_w(ay8912, state->generic_space(), 0, snapdata[38]);
2366      }
2367
2368      pSource = snapdata + header_size;
2369
2370      if (z80_type == SPECTRUM_Z80_SNAPSHOT_48K)
2371         /* Ensure 48K Basic ROM is used */
2372         spectrum_page_basicrom(machine);
2373
2374      do
2375      {
2376         unsigned short length;
2377         UINT8 page;
2378         int Dest = 0;
2379
2380         length = (pSource[0] & 0x0ff) | ((pSource[1] & 0x0ff) << 8);
2381         page = pSource[2];
2382
2383         if (z80_type == SPECTRUM_Z80_SNAPSHOT_48K || z80_type == SPECTRUM_Z80_SNAPSHOT_TS2068)
2384         {
2385            switch (page)
2386            {
2387               case 4: Dest = 0x08000; break;
2388               case 5: Dest = 0x0c000; break;
2389               case 8: Dest = 0x04000; break;
2390               default: Dest = 0; break;
2391            }
2392         }
2393         else
2394         {
2395            /* 3 = bank 0, 4 = bank 1 ... 10 = bank 7 */
2396            if ((page >= 3) && (page <= 10))
2397            {
2398               /* Page the appropriate bank into 0xc000 - 0xfff */
2399               state->m_port_7ffd_data = page - 3;
2400               spectrum_update_paging(machine);
2401               Dest = 0x0c000;
2402            }
2403            else
2404               /* Other values correspond to ROM pages */
2405               Dest = 0x0;
2406         }
2407
2408         if (Dest != 0)
2409         {
2410            if (length == 0x0ffff)
2411            {
2412               /* block is uncompressed */
2413               logerror("Not compressed\n");
2414
2415               /* not compressed */
2416               for (i = 0; i < 16384; i++)
2417                  space.write_byte(i + Dest, pSource[i]);
2418            }
2419            else
2420            {
2421               logerror("Compressed\n");
2422
2423               /* block is compressed */
2424               spectrum_z80_decompress_block(machine,&pSource[3], Dest, 16384);
2425            }
2426         }
2427
2428         /* go to next block */
2429         pSource += (3 + length);
2430      }
2431      while ((pSource - snapdata) < snapsize);
2432
2433      if ((state->m_port_7ffd_data != -1) && (z80_type != SPECTRUM_Z80_SNAPSHOT_48K))
2434      {
2435         /* Set up paging */
2436         state->m_port_7ffd_data = (snapdata[35] & 0x0ff);
2437         spectrum_update_paging(machine);
2438      }
2439      if ((z80_type == SPECTRUM_Z80_SNAPSHOT_48K) && !strcmp(machine.system().name,"ts2068"))
2440      {
2441         state->m_port_f4_data = 0x03;
2442         state->m_port_ff_data = 0x00;
2443         state->ts2068_update_memory();
2444      }
2445      if (z80_type == SPECTRUM_Z80_SNAPSHOT_TS2068 && !strcmp(machine.system().name,"ts2068"))
2446      {
2447         state->m_port_f4_data = snapdata[35];
2448         state->m_port_ff_data = snapdata[36];
2449         state->ts2068_update_memory();
2450      }
2451   }
2452}
2453
2454QUICKLOAD_LOAD(spectrum)
2455{
2456   UINT8 *quickload_data = NULL;
2457
2458   quickload_data = (UINT8*)malloc(quickload_size);
2459   if (!quickload_data)
2460      goto error;
2461
2462   image.fread(quickload_data, quickload_size);
2463
2464   if (!mame_stricmp(file_type, "scr"))
2465   {
2466      if ((quickload_size != SCR_SIZE) && (quickload_size != SCR_BITMAP))
2467      {
2468         logerror("Invalid .SCR file size.\n");
2469         goto error;
2470      }
2471      spectrum_setup_scr(image.device().machine(), quickload_data, quickload_size);
2472   }
2473   else if (!mame_stricmp(file_type, "raw"))
2474   {
2475      if (quickload_size != RAW_SIZE)
2476      {
2477         logerror("Invalid .RAW file size.\n");
2478         goto error;
2479      }
2480      spectrum_setup_raw(image.device().machine(), quickload_data, quickload_size);
2481   }
2482
2483   free(quickload_data);
2484
2485   return IMAGE_INIT_PASS;
2486
2487error:
2488   if (quickload_data)
2489      free(quickload_data);
2490   return IMAGE_INIT_FAIL;
2491}
2492
2493/*******************************************************************
2494 *
2495 *      Load a .SCR file.
2496 *
2497 *      .SCR files are just a binary dump of the ZX Spectrum's
2498 *      display file, which is 256x192 pixels large.
2499 *
2500 *      These file are created using the Sinclair BASIC command
2501 *
2502 *      SAVE "filename" SCREEN$
2503 *
2504 *      where the keyword "SCREEN$" is a shortcut for "CODE 16384,6912"
2505 *      i.e. the loading address and the length of the data.
2506 *
2507 *      The format is organized as follows:
2508 *
2509 *      Offset   Size    Description
2510 *      -------- ------- -------------------------------------------------
2511 *      0        6144    Screen bitmap
2512 *      6144     768     Screen attributes
2513 *
2514 *      Some utilities and emulators support a B&W version of this
2515 *      format, which stores only the bitmap. These files can't be
2516 *      produced using the SAVE SCREEN$ command - rather they're
2517 *      created by the command
2518 *
2519 *      SAVE "filename" CODE 16384,6144
2520 *
2521 *******************************************************************/
2522void spectrum_setup_scr(running_machine &machine, UINT8 *quickdata, UINT32 quicksize)
2523{
2524   int i;
2525   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
2526
2527   for (i = 0; i < quicksize; i++)
2528      space.write_byte(i + BASE_RAM, quickdata[i]);
2529
2530   log_quickload(quicksize == SCR_SIZE ? "SCREEN$" : "SCREEN$ (Mono)", BASE_RAM, quicksize, 0, EXEC_NA);
2531}
2532
2533/*******************************************************************
2534 *
2535 *      Load a .RAW file.
2536 *
2537 *      .RAW files are a binary dump of the ZX Spectrum RAM
2538 *      and are created using the Sinclair BASIC command
2539 *
2540 *      SAVE *"b" CODE 16384,49152
2541 *
2542 *      which copies the whole RAM to the Interface 1's RS232 interface.
2543 *      The resulting file is always 49161 bytes long.
2544 *
2545 *      The format is organized as follows:
2546 *
2547 *      Offset  Size    Description (all registers stored with LSB first)
2548 *      ------- ------- -------------------------------------------------
2549 *      0       1       0x03 (BYTES file type)
2550 *      1       2       Image size
2551 *      3       2       Image start address
2552 *      5       4       0xFF
2553 *
2554 *      Since the size and the start address are encoded in the header,
2555 *      it would be possible to create .RAW images of any part of the RAM.
2556 *      However, no image of such type has ever surfaced.
2557 *
2558 *******************************************************************/
2559void spectrum_setup_raw(running_machine &machine, UINT8 *quickdata, UINT32 quicksize)
2560{
2561   int i;
2562   UINT8 data;
2563   UINT16 start, len;
2564   spectrum_state *state = machine.driver_data<spectrum_state>();
2565   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
2566
2567   start = (quickdata[RAW_OFFSET + 4] << 8) | quickdata[RAW_OFFSET + 3];
2568   len   = (quickdata[RAW_OFFSET + 2] << 8) | quickdata[RAW_OFFSET + 1];
2569
2570   for (i = 0; i < len; i++)
2571      space.write_byte(i + start, quickdata[i + RAW_HDR]);
2572
2573   /* Set border color */
2574   data = (space.read_byte(0x5c48) >> 3) & 0x07; // Get the current border color from BORDCR system variable.
2575   state->m_port_fe_data = (state->m_port_fe_data & 0xf8) | data;
2576   spectrum_border_update(machine, data);
2577   logerror("Border color:%02X\n", data);
2578
2579   log_quickload("BYTES", start, len, 0, EXEC_NA);
2580}
Property changes on: trunk/src/mess/machine/spec_snqk.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/spec_snqk.h
r0r21310
1/*****************************************************************************
2 *
3 * machine/spec_snqk.h
4 *
5 ****************************************************************************/
6
7#ifndef __SPEC_SNQK_H__
8#define __SPEC_SNQK_H__
9
10#include "imagedev/snapquik.h"
11#include "imagedev/cartslot.h"
12
13void spectrum_setup_sna(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
14void spectrum_setup_z80(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
15void spectrum_setup_sp(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
16void spectrum_setup_ach(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
17void spectrum_setup_prg(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
18void spectrum_setup_plusd(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
19void spectrum_setup_sem(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
20void spectrum_setup_sit(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
21void spectrum_setup_zx(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
22void spectrum_setup_snp(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
23void spectrum_setup_snx(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
24void spectrum_setup_frz(running_machine &machine, UINT8 *snapdata, UINT32 snapsize);
25
26void spectrum_setup_scr(running_machine &machine, UINT8 *quickdata, UINT32 quicksize);
27void spectrum_setup_raw(running_machine &machine, UINT8 *quickdata, UINT32 quicksize);
28
29#define BASE_RAM      0x4000
30#define SPECTRUM_BANK 0x4000
31
32/*****************************************************************************
33 *
34 * .SNA format (used by JPP)
35 *
36 ****************************************************************************/
37#define SNA48_OFFSET  0
38#define SNA48_HDR     27
39#define SNA48_SIZE    (SNA48_HDR + 3*SPECTRUM_BANK)
40
41#define SNA128_OFFSET (SNA48_HDR + 3*SPECTRUM_BANK)
42#define SNA128_HDR    4
43#define SNA128_SIZE_1 (SNA48_HDR + 3*SPECTRUM_BANK + SNA128_HDR + 5*SPECTRUM_BANK)
44#define SNA128_SIZE_2 (SNA48_HDR + 3*SPECTRUM_BANK + SNA128_HDR + 6*SPECTRUM_BANK)
45
46/*****************************************************************************
47 *
48 * .SP format (used by VGASPEC and Spanish Spectrum emulator)
49 *
50 ****************************************************************************/
51#define SP_OLD_HDR      32
52#define SP_NEW_HDR      38
53#define SP_OLD_SIZE     (SP_OLD_HDR + 3*SPECTRUM_BANK)
54#define SP_NEW_SIZE_16K (SP_NEW_HDR + 1*SPECTRUM_BANK)
55#define SP_NEW_SIZE_48K (SP_NEW_HDR + 3*SPECTRUM_BANK)
56
57/*****************************************************************************
58 *
59 * .ACH format (used by !Speccy)
60 *
61 ****************************************************************************/
62#define ACH_OFFSET 0
63#define ACH_HDR    256
64#define ACH_SIZE   (ACH_HDR + BASE_RAM + 3*SPECTRUM_BANK)
65
66/*****************************************************************************
67 *
68 * .PRG format (used by SpecEm)
69 *
70 ****************************************************************************/
71#define PRG_OFFSET 0
72#define PRG_HDR    256
73#define PRG_SIZE   (PRG_HDR + 3*SPECTRUM_BANK)
74
75/*****************************************************************************
76 *
77 * .PLUSD format (used by FUSE)
78 *
79 ****************************************************************************/
80#define PLUSD_OFFSET 0
81#define PLUSD48_HDR  22
82#define PLUSD48_SIZE (PLUSD48_HDR + 3*SPECTRUM_BANK)
83
84#define PLUSD128_HDR  23
85#define PLUSD128_SIZE (PLUSD128_HDR + 8*SPECTRUM_BANK)
86
87/*****************************************************************************
88 *
89 * .SEM format (used by SpecEmu)
90 *
91 ****************************************************************************/
92#define SEM_SIGNATURE 6
93#define SEM_OFFSET    49158
94#define SEM_HDR       34
95#define SEM_SIZE      (SEM_SIGNATURE + 3*SPECTRUM_BANK + SEM_HDR)
96
97/*****************************************************************************
98 *
99 * .SIT format (used by Sinclair)
100 *
101 ****************************************************************************/
102#define SIT_OFFSET 0
103#define SIT_HDR    28
104#define SIT_SIZE   (SIT_HDR + BASE_RAM + 3*SPECTRUM_BANK)
105
106/*****************************************************************************
107 *
108 * .ZX format (used by KGB)
109 *
110 ****************************************************************************/
111#define ZX_OFFSET 49284
112#define ZX_HDR    202
113#define ZX_SIZE   (132 + 3*SPECTRUM_BANK + ZX_HDR)
114
115/*****************************************************************************
116 *
117 * .SNP format (used by Nuclear ZX)
118 *
119 ****************************************************************************/
120#define SNP_OFFSET 49152
121#define SNP_HDR    31
122#define SNP_SIZE   (3*SPECTRUM_BANK + SNP_HDR)
123
124/*****************************************************************************
125 *
126 * .SNX format (used by Specci)
127 *
128 ****************************************************************************/
129#define SNX_OFFSET 0
130#define SNX_HDR    43
131
132#define SNX_COMPRESSED   0xff
133#define SNX_UNCOMPRESSED 0x00
134
135/*****************************************************************************
136 *
137 * .FRZ format (used by CBSpeccy, ZX-Live and ASp)
138 *
139 ****************************************************************************/
140#define FRZ_OFFSET 0
141#define FRZ_HDR    42
142#define FRZ_SIZE   (FRZ_HDR + 8*SPECTRUM_BANK)
143
144enum SPECTRUM_SNAPSHOT_TYPE
145{
146   SPECTRUM_SNAPSHOT_NONE,
147   SPECTRUM_SNAPSHOT_SNA,
148   SPECTRUM_SNAPSHOT_Z80,
149   SPECTRUM_SNAPSHOT_SP,
150   SPECTRUM_TAPEFILE_TAP
151};
152
153enum SPECTRUM_Z80_SNAPSHOT_TYPE {
154   SPECTRUM_Z80_SNAPSHOT_INVALID,
155   SPECTRUM_Z80_SNAPSHOT_48K_OLD,
156   SPECTRUM_Z80_SNAPSHOT_48K,
157   SPECTRUM_Z80_SNAPSHOT_SAMRAM,
158   SPECTRUM_Z80_SNAPSHOT_128K,
159   SPECTRUM_Z80_SNAPSHOT_TS2068
160};
161
162/*****************************************************************************
163 *
164 * .SCR format (used by many emulators)
165 *
166 ****************************************************************************/
167#define SCR_BITMAP 6144
168#define SCR_ATTR   768
169#define SCR_SIZE   (SCR_BITMAP + SCR_ATTR)
170
171/*****************************************************************************
172 *
173 * .RAW format (used by many emulators)
174 *
175 ****************************************************************************/
176#define RAW_OFFSET 0
177#define RAW_HDR    9
178#define RAW_SIZE   (RAW_HDR + 3*SPECTRUM_BANK)
179
180SNAPSHOT_LOAD( spectrum );
181QUICKLOAD_LOAD( spectrum );
182
183#endif  /* __SPEC_SNQK_H__ */
Property changes on: trunk/src/mess/machine/spec_snqk.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/z80bin.c
r0r21310
1#include "emu.h"
2#include "machine/z80bin.h"
3
4/*-------------------------------------------------
5    z80bin_load_file - load a z80bin file into
6    memory
7-------------------------------------------------*/
8
9int z80bin_load_file(device_image_interface *image, const char *file_type, UINT16 *exec_addr, UINT16 *start_addr, UINT16 *end_addr )
10{
11   int ch;
12   UINT16 args[3];
13   UINT16 i=0, j, size;
14   UINT8 data;
15   char pgmname[256];
16   char message[256];
17
18   image->fseek(7, SEEK_SET);
19
20   while((ch = image->fgetc()) != 0x1A)
21   {
22      if (ch == EOF)
23      {
24         image->seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file name");
25         image->message(" Unexpected EOF while getting file name");
26         return IMAGE_INIT_FAIL;
27      }
28
29      if (ch != '\0')
30      {
31         if (i >= (ARRAY_LENGTH(pgmname) - 1))
32         {
33            image->seterror(IMAGE_ERROR_INVALIDIMAGE, "File name too long");
34            image->message(" File name too long");
35            return IMAGE_INIT_FAIL;
36         }
37
38         pgmname[i] = ch;    /* build program name */
39         i++;
40      }
41   }
42
43   pgmname[i] = '\0';  /* terminate string with a null */
44
45   if (image->fread(args, sizeof(args)) != sizeof(args))
46   {
47      image->seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file size");
48      image->message(" Unexpected EOF while getting file size");
49      return IMAGE_INIT_FAIL;
50   }
51
52   exec_addr[0] = LITTLE_ENDIANIZE_INT16(args[0]);
53   start_addr[0] = LITTLE_ENDIANIZE_INT16(args[1]);
54   end_addr[0] = LITTLE_ENDIANIZE_INT16(args[2]);
55
56   size = (end_addr[0] - start_addr[0] + 1) & 0xffff;
57
58   /* display a message about the loaded quickload */
59   image->message(" %s\nsize=%04X : start=%04X : end=%04X : exec=%04X",pgmname,size,start_addr[0],end_addr[0],exec_addr[0]);
60
61   for (i = 0; i < size; i++)
62   {
63      j = (start_addr[0] + i) & 0xffff;
64      if (image->fread(&data, 1) != 1)
65      {
66         snprintf(message, ARRAY_LENGTH(message), "%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
67         image->seterror(IMAGE_ERROR_INVALIDIMAGE, message);
68         image->message("%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
69         return IMAGE_INIT_FAIL;
70      }
71      image->device().machine().device("maincpu")->memory().space(AS_PROGRAM).write_byte(j, data);
72   }
73
74   return IMAGE_INIT_PASS;
75}
Property changes on: trunk/src/mess/machine/z80bin.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/z80bin.h
r0r21310
1/*********************************************************************
2
3    machine/z80bin.h
4
5    Quickload code for Z80 bin format
6
7*********************************************************************/
8
9#pragma once
10
11#ifndef __Z80_BIN__
12#define __Z80_BIN__
13
14int z80bin_load_file(device_image_interface *image, const char *file_type, UINT16 *exec_addr, UINT16 *start_addr, UINT16 *end_addr );
15
16#endif
Property changes on: trunk/src/mess/machine/z80bin.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/super80.c
r21309r21310
11/* Super80.c written by Robbbert, 2005-2009. See driver source for documentation. */
22
33#include "includes/super80.h"
4#include "machine/z80bin.h"
45
5
66/**************************** PIO ******************************************************************************/
77
88
r21309r21310
228228{
229229   driver_init_common(machine());
230230}
231
232/*-------------------------------------------------
233    QUICKLOAD_LOAD( super80 )
234-------------------------------------------------*/
235
236QUICKLOAD_LOAD( super80 )
237{
238   UINT16 exec_addr, start_addr, end_addr;
239   int autorun;
240
241   /* load the binary into memory */
242   if (z80bin_load_file(&image, file_type, &exec_addr, &start_addr, &end_addr) == IMAGE_INIT_FAIL)
243      return IMAGE_INIT_FAIL;
244
245   /* is this file executable? */
246   if (exec_addr != 0xffff)
247   {
248      /* check to see if autorun is on (I hate how this works) */
249      autorun = image.device().machine().root_device().ioport("CONFIG")->read_safe(0xFF) & 1;
250
251      if (autorun)
252         image.device().machine().device("maincpu")->state().set_pc(exec_addr);
253   }
254
255   return IMAGE_INIT_PASS;
256}
No newline at end of file
trunk/src/mess/machine/c64exp.h
r21309r21310
3838#define __C64_EXPANSION_SLOT__
3939
4040#include "emu.h"
41#include "formats/cbm_crt.h"
41#include "machine/cbm_crt.h"
4242
4343
4444
trunk/src/mess/machine/vic10exp.c
r21309r21310
99
1010#include "emu.h"
1111#include "emuopts.h"
12#include "formats/cbm_crt.h"
12#include "machine/cbm_crt.h"
1313#include "formats/imageutl.h"
1414#include "machine/vic10exp.h"
1515
trunk/src/mess/machine/vic10exp.h
r21309r21310
3838#define __VIC10_EXPANSION_SLOT__
3939
4040#include "emu.h"
41#include "formats/cbm_crt.h"
41#include "machine/cbm_crt.h"
4242
4343
4444
trunk/src/mess/machine/mbee.c
r21309r21310
1010
1111#include "emu.h"
1212#include "includes/mbee.h"
13#include "machine/z80bin.h"
1314
14
1515/***********************************************************
1616
1717    PIO
r21309r21310
815815
816816   return IMAGE_INIT_PASS;
817817}
818
819
820/*-------------------------------------------------
821    QUICKLOAD_LOAD( mbee_z80bin )
822-------------------------------------------------*/
823
824QUICKLOAD_LOAD( mbee_z80bin )
825{
826   UINT16 execute_address, start_addr, end_addr;
827   int autorun;
828
829   /* load the binary into memory */
830   if (z80bin_load_file(&image, file_type, &execute_address, &start_addr, &end_addr) == IMAGE_INIT_FAIL)
831      return IMAGE_INIT_FAIL;
832
833   /* is this file executable? */
834   if (execute_address != 0xffff)
835   {
836      /* check to see if autorun is on (I hate how this works) */
837      autorun = image.device().machine().root_device().ioport("CONFIG")->read_safe(0xFF) & 1;
838
839      device_t *cpu = image.device().machine().device("maincpu");
840      address_space &space = image.device().machine().device("maincpu")->memory().space(AS_PROGRAM);
841
842      space.write_word(0xa6, execute_address);            /* fix the EXEC command */
843
844      if (autorun)
845      {
846         space.write_word(0xa2, execute_address);        /* fix warm-start vector to get around some copy-protections */
847         cpu->state().set_pc(execute_address);
848      }
849      else
850      {
851         space.write_word(0xa2, 0x8517);
852      }
853   }
854
855   return IMAGE_INIT_PASS;
856}
No newline at end of file
trunk/src/mess/machine/cbm_crt.c
r0r21310
1/*********************************************************************
2
3    machine/cbm_crt.c
4
5    Commodore VIC-20/C64 cartridge images
6
7*********************************************************************/
8
9#include "machine/cbm_crt.h"
10
11
12
13//**************************************************************************
14//  MACROS/CONSTANTS
15//**************************************************************************
16
17#define LOG 0
18
19
20// slot names for the C64 cartridge types
21static const char * CRT_C64_SLOT_NAMES[_CRT_C64_COUNT] =
22{
23   "standard",
24   UNSUPPORTED,
25   UNSUPPORTED,
26   UNSUPPORTED,
27   "simons_basic",
28   "ocean",
29   UNSUPPORTED,
30   "fun_play",
31   "super_games",
32   UNSUPPORTED,
33   "epyxfastload",
34   "westermann",
35   "rex",
36   UNSUPPORTED,
37   "magic_formel",
38   "system3",
39   "warp_speed",
40   "dinamic",
41   "zaxxon",
42   "magic_desk",
43   UNSUPPORTED,
44   "comal80",
45   "struct_basic",
46   "ross",
47   "ep64",
48   "ep7x8",
49   "dela_ep256",
50   "rex_ep256",
51   "mikroasm",
52   UNSUPPORTED,
53   UNSUPPORTED,
54   "stardos",
55   UNSUPPORTED,
56   UNSUPPORTED,
57   UNSUPPORTED,
58   UNSUPPORTED,
59   UNSUPPORTED,
60   UNSUPPORTED,
61   UNSUPPORTED,
62   UNSUPPORTED,
63   UNSUPPORTED,
64   "ieee488",
65   UNSUPPORTED,
66   UNSUPPORTED,
67   "exos",
68   UNSUPPORTED,
69   UNSUPPORTED,
70   UNSUPPORTED,
71   "super_explode",
72   UNSUPPORTED,
73   UNSUPPORTED,
74   "mach5",
75   UNSUPPORTED,
76   "pagefox",
77   UNSUPPORTED,
78   "silverrock"
79};
80
81
82
83//**************************************************************************
84//  IMPLEMENTATION
85//**************************************************************************
86
87//-------------------------------------------------
88//  cbm_crt_get_card - get slot interface card
89//-------------------------------------------------
90
91const char * cbm_crt_get_card(core_file *file)
92{
93   // read the header
94   cbm_crt_header header;
95   core_fread(file, &header, CRT_HEADER_LENGTH);
96
97   if (memcmp(header.signature, CRT_SIGNATURE, 16) == 0)
98   {
99      UINT16 hardware = pick_integer_be(header.hardware, 0, 2);
100
101      return CRT_C64_SLOT_NAMES[hardware];
102   }
103
104   return NULL;
105}
106
107
108//-------------------------------------------------
109//  cbm_crt_read_header - read cartridge header
110//-------------------------------------------------
111
112bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game)
113{
114   // read the header
115   cbm_crt_header header;
116   core_fread(file, &header, CRT_HEADER_LENGTH);
117
118   if (memcmp(header.signature, CRT_SIGNATURE, 16) != 0)
119      return false;
120
121   UINT16 hardware = pick_integer_be(header.hardware, 0, 2);
122   *exrom = header.exrom;
123   *game = header.game;
124
125   if (LOG)
126   {
127      logerror("Name: %s\n", header.name);
128      logerror("Hardware: %04x\n", hardware);
129      logerror("Slot device: %s\n", CRT_C64_SLOT_NAMES[hardware]);
130      logerror("EXROM: %u\n", header.exrom);
131      logerror("GAME: %u\n", header.game);
132   }
133
134   // determine ROM region lengths
135   while (!core_feof(file))
136   {
137      cbm_crt_chip chip;
138      core_fread(file, &chip, CRT_CHIP_LENGTH);
139
140      UINT16 address = pick_integer_be(chip.start_address, 0, 2);
141      UINT16 size = pick_integer_be(chip.image_size, 0, 2);
142      UINT16 type = pick_integer_be(chip.chip_type, 0, 2);
143
144      if (LOG)
145      {
146         logerror("CHIP Address: %04x\n", address);
147         logerror("CHIP Size: %04x\n", size);
148         logerror("CHIP Type: %04x\n", type);
149      }
150
151      switch (address)
152      {
153      case 0x8000: *roml_size += size; break;
154      case 0xa000: *romh_size += size; break;
155      case 0xe000: *romh_size += size; break;
156      default: logerror("Invalid CHIP loading address!\n"); break;
157      }
158
159      core_fseek(file, size, SEEK_CUR);
160   }
161
162   return true;
163}
164
165
166//-------------------------------------------------
167//  cbm_crt_read_data - read cartridge data
168//-------------------------------------------------
169
170bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh)
171{
172   offs_t roml_offset = 0;
173   offs_t romh_offset = 0;
174
175   core_fseek(file, CRT_HEADER_LENGTH, SEEK_SET);
176
177   while (!core_feof(file))
178   {
179      cbm_crt_chip chip;
180      core_fread(file, &chip, CRT_CHIP_LENGTH);
181
182      UINT16 address = pick_integer_be(chip.start_address, 0, 2);
183      UINT16 size = pick_integer_be(chip.image_size, 0, 2);
184
185      switch (address)
186      {
187      case 0x8000: core_fread(file, roml + roml_offset, size); roml_offset += size; break;
188      case 0xa000: core_fread(file, romh + romh_offset, size); romh_offset += size; break;
189      case 0xe000: core_fread(file, romh + romh_offset, size); romh_offset += size; break;
190      }
191   }
192
193   return true;
194}
Property changes on: trunk/src/mess/machine/cbm_crt.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/cbm_crt.h
r0r21310
1/*********************************************************************
2
3    machine/cbm_crt.h
4
5    Commodore VIC-20/C64 cartridge images
6
7*********************************************************************/
8
9#pragma once
10
11#ifndef __CBM_CRT__
12#define __CBM_CRT__
13
14#include "emu.h"
15#include "formats/imageutl.h"
16
17
18
19//**************************************************************************
20//  MACROS/CONSTANTS
21//**************************************************************************
22
23#define CRT_SIGNATURE       "C64 CARTRIDGE   "
24
25#define CRT_HEADER_LENGTH   0x40
26#define CRT_CHIP_LENGTH     0x10
27
28#define UNSUPPORTED         "standard"
29
30
31// VIC-20 cartridge types
32enum
33{
34   CRT_VIC20_STANDARD = 1,
35   CRT_VIC20_MEGACART,
36   CRT_VIC20_FINAL_EXPANSION,
37   CRT_VIC20_FP,
38   _CRT_VIC20_COUNT
39};
40
41
42// C64 cartridge types
43enum
44{
45   CRT_C64_STANDARD = 0,
46   CRT_C64_ACTION_REPLAY,
47   CRT_C64_KCS_POWER,
48   CRT_C64_FINAL_III,
49   CRT_C64_SIMONS_BASIC,
50   CRT_C64_OCEAN,
51   CRT_C64_EXPERT,
52   CRT_C64_FUNPLAY,
53   CRT_C64_SUPER_GAMES,
54   CRT_C64_ATOMIC_POWER,
55   CRT_C64_EPYX_FASTLOAD,
56   CRT_C64_WESTERMANN,
57   CRT_C64_REX,
58   CRT_C64_FINAL_I,
59   CRT_C64_MAGIC_FORMEL,
60   CRT_C64_GS,
61   CRT_C64_WARPSPEED,
62   CRT_C64_DINAMIC,
63   CRT_C64_ZAXXON,
64   CRT_C64_MAGIC_DESK,
65   CRT_C64_SUPER_SNAPSHOT_V5,
66   CRT_C64_COMAL80,
67   CRT_C64_STRUCTURED_BASIC,
68   CRT_C64_ROSS,
69   CRT_C64_DELA_EP64,
70   CRT_C64_DELA_EP7x8,
71   CRT_C64_DELA_EP256,
72   CRT_C64_REX_EP256,
73   CRT_C64_MIKRO_ASSEMBLER,
74   CRT_C64_FINAL_PLUS,
75   CRT_C64_ACTION_REPLAY4,
76   CRT_C64_STARDOS,
77   CRT_C64_EASYFLASH,
78   CRT_C64_EASYFLASH_XBANK,
79   CRT_C64_CAPTURE,
80   CRT_C64_ACTION_REPLAY3,
81   CRT_C64_RETRO_REPLAY,
82   CRT_C64_MMC64,
83   CRT_C64_MMC_REPLAY,
84   CRT_C64_IDE64,
85   CRT_C64_SUPER_SNAPSHOT,
86   CRT_C64_IEEE488,
87   CRT_C64_GAME_KILLER,
88   CRT_C64_P64,
89   CRT_C64_EXOS,
90   CRT_C64_FREEZE_FRAME,
91   CRT_C64_FREEZE_MACHINE,
92   CRT_C64_SNAPSHOT64,
93   CRT_C64_SUPER_EXPLODE_V5,
94   CRT_C64_MAGIC_VOICE,
95   CRT_C64_ACTION_REPLAY2,
96   CRT_C64_MACH5,
97   CRT_C64_DIASHOW_MAKER,
98   CRT_C64_PAGEFOX,
99   CRT_C64_KINGSOFT,
100   CRT_C64_SILVERROCK,
101   _CRT_C64_COUNT
102};
103
104
105// chip types
106enum
107{
108   CRT_CHIP_TYPE_ROM = 0,
109   CRT_CHIP_TYPE_RAM,
110   CRT_CHIP_TYPE_FLASH_ROM
111};
112
113
114
115//**************************************************************************
116//  TYPE DEFINITIONS
117//**************************************************************************
118
119struct cbm_crt_header
120{
121   UINT8 signature[16];
122   UINT8 header_length[4];
123   UINT8 version[2];
124   UINT8 hardware[2];
125   UINT8 exrom;
126   UINT8 game;
127   UINT8 reserved[6];
128   UINT8 name[32];
129};
130
131
132struct cbm_crt_chip
133{
134   UINT8 signature[4];
135   UINT8 packet_length[4];
136   UINT8 chip_type[2];
137   UINT8 bank[2];
138   UINT8 start_address[2];
139   UINT8 image_size[2];
140};
141
142
143
144//**************************************************************************
145//  FUNCTION PROTOTYPES
146//**************************************************************************
147
148const char * cbm_crt_get_card(core_file *file);
149bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game);
150bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh);
151
152
153#endif
Property changes on: trunk/src/mess/machine/cbm_crt.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/vic20exp.c
r21309r21310
99
1010#include "emu.h"
1111#include "emuopts.h"
12#include "formats/cbm_crt.h"
12#include "machine/cbm_crt.h"
1313#include "machine/vic20exp.h"
1414#include "formats/imageutl.h"
1515
trunk/src/mess/machine/cbm_snqk.c
r0r21310
1/***********************************************
2
3 CBM Quickloads
4
5 ***********************************************/
6
7#include "emu.h"
8#include "machine/cbm_snqk.h"
9
10/* prg file format
11 * sfx file format
12 * sda file format
13 * 0 lsb 16bit address
14 * 2 chip data */
15
16/* p00 file format (p00 .. p63, s00 .. s63, ..)
17 * 0x0000 C64File
18 * 0x0007 0
19 * 0x0008 Name in commodore encoding?
20 * 0x0018 0 0
21 * 0x001a lsb 16bit address
22 * 0x001c data */
23
24
25int general_cbm_loadsnap( device_image_interface &image, const char *file_type, int snapshot_size,
26                        offs_t offset, void (*cbm_sethiaddress)(running_machine &machine, UINT16 hiaddress) )
27{
28   char buffer[7];
29   UINT8 *data = NULL;
30   UINT32 bytesread;
31   UINT16 address = 0;
32   int i;
33   address_space &space = image.device().machine().firstcpu->space(AS_PROGRAM);
34
35   if (!file_type)
36      goto error;
37
38   if (!mame_stricmp(file_type, "prg"))
39   {
40      /* prg files */
41   }
42   else if (!mame_stricmp(file_type, "p00"))
43   {
44      /* p00 files */
45      if (image.fread( buffer, sizeof(buffer)) != sizeof(buffer))
46         goto error;
47      if (memcmp(buffer, "C64File", sizeof(buffer)))
48         goto error;
49      image.fseek(26, SEEK_SET);
50      snapshot_size -= 26;
51   }
52   else if (!mame_stricmp(file_type, "t64"))
53   {
54      /* t64 files - for GB64 Single T64s loading to x0801 - header is always the same size */
55      if (image.fread( buffer, sizeof(buffer)) != sizeof(buffer))
56         goto error;
57      if (memcmp(buffer, "C64 tape image file", sizeof(buffer)))
58         goto error;
59      image.fseek(94, SEEK_SET);
60      snapshot_size -= 94;
61   }
62   else
63   {
64      goto error;
65   }
66
67   image.fread( &address, 2);
68   address = LITTLE_ENDIANIZE_INT16(address);
69   if (!mame_stricmp(file_type, "t64"))
70      address = 2049;
71   snapshot_size -= 2;
72
73   data = (UINT8*)malloc(snapshot_size);
74   if (!data)
75      goto error;
76
77   bytesread = image.fread( data, snapshot_size);
78   if (bytesread != snapshot_size)
79      goto error;
80
81   for (i = 0; i < snapshot_size; i++)
82      space.write_byte(address + i + offset, data[i]);
83
84   cbm_sethiaddress(image.device().machine(), address + snapshot_size);
85   free(data);
86   return IMAGE_INIT_PASS;
87
88error:
89   if (data)
90      free(data);
91   return IMAGE_INIT_FAIL;
92}
93
94void cbm_quick_sethiaddress( running_machine &machine, UINT16 hiaddress )
95{
96   address_space &space = machine.firstcpu->space(AS_PROGRAM);
97
98   space.write_byte(0x31, hiaddress & 0xff);
99   space.write_byte(0x2f, hiaddress & 0xff);
100   space.write_byte(0x2d, hiaddress & 0xff);
101   space.write_byte(0x32, hiaddress >> 8);
102   space.write_byte(0x30, hiaddress >> 8);
103   space.write_byte(0x2e, hiaddress >> 8);
104}
Property changes on: trunk/src/mess/machine/cbm_snqk.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/cbm_snqk.h
r0r21310
1/***********************************************
2
3    CBM Quickloads
4
5 ***********************************************/
6
7#ifndef __CBM_SNQK_H__
8#define __CBM_SNQK_H__
9
10#include "imagedev/snapquik.h"
11
12#define CBM_QUICKLOAD_DELAY_SECONDS 3
13
14int general_cbm_loadsnap( device_image_interface &image, const char *file_type, int snapshot_size,
15                        offs_t offset, void (*cbm_sethiaddress)(running_machine &machine, UINT16 hiaddress) );
16void cbm_quick_sethiaddress( running_machine &machine, UINT16 hiaddress );
17
18#endif  /* __CBM_SNQK_H__ */
Property changes on: trunk/src/mess/machine/cbm_snqk.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/includes/c128.h
r21309r21310
44#define __C128__
55
66#include "emu.h"
7#include "formats/cbm_snqk.h"
7#include "machine/cbm_snqk.h"
88#include "cpu/m6502/m8502.h"
99#include "machine/6526cia.h"
1010#include "machine/c64exp.h"
trunk/src/mess/includes/c64.h
r21309r21310
55
66#include "emu.h"
77#include "cpu/m6502/m6510.h"
8#include "formats/cbm_snqk.h"
8#include "machine/cbm_snqk.h"
99#include "machine/c64exp.h"
1010#include "machine/c64user.h"
1111#include "machine/cbmiec.h"
trunk/src/mess/includes/super80.h
r21309r21310
120120/*----------- defined in machine/super80.c -----------*/
121121
122122extern const z80pio_interface super80_pio_intf;
123QUICKLOAD_LOAD( super80 );
No newline at end of file
trunk/src/mess/includes/vic20.h
r21309r21310
66
77#include "emu.h"
88#include "includes/cbm.h"
9#include "formats/cbm_snqk.h"
9#include "machine/cbm_snqk.h"
1010#include "cpu/m6502/m6510.h"
1111#include "imagedev/cartslot.h"
1212#include "machine/6522via.h"
trunk/src/mess/includes/plus4.h
r21309r21310
55
66#include "emu.h"
77#include "cpu/m6502/m7501.h"
8#include "formats/cbm_snqk.h"
8#include "machine/cbm_snqk.h"
99#include "machine/cbmiec.h"
1010#include "machine/cbmipt.h"
1111#include "machine/mos6529.h"
trunk/src/mess/includes/cbm2.h
r21309r21310
66#include "emu.h"
77#include "cpu/m6502/m6509.h"
88#include "cpu/i86/i86.h"
9#include "formats/cbm_snqk.h"
9#include "machine/cbm_snqk.h"
1010#include "includes/cbm.h"
1111#include "machine/6525tpi.h"
1212#include "machine/cbm2exp.h"
trunk/src/mess/includes/sorcerer.h
r21309r21310
9494
9595/*----------- defined in machine/sorcerer.c -----------*/
9696SNAPSHOT_LOAD( sorcerer );
97QUICKLOAD_LOAD(sorcerer);
9798
9899#endif /* SORCERER_H_ */
trunk/src/mess/includes/mbee.h
r21309r21310
216216extern const z80pio_interface mbee_z80pio_intf;
217217
218218QUICKLOAD_LOAD( mbee );
219QUICKLOAD_LOAD( mbee_z80bin );
219220
220
221221/*----------- defined in video/mbee.c -----------*/
222222
223223MC6845_UPDATE_ROW( mbee_update_row );
trunk/src/mess/includes/pet2001.h
r21309r21310
55
66#include "emu.h"
77#include "cpu/m6502/m6502.h"
8#include "formats/cbm_snqk.h"
8#include "machine/cbm_snqk.h"
99#include "machine/6522via.h"
1010#include "machine/6821pia.h"
1111#include "machine/cbmipt.h"
trunk/src/mess/messcore.mak
r21309r21310
3939# MESS directories
4040MESS_AUDIO = $(MESSOBJ)/audio
4141MESS_DRIVERS = $(MESSOBJ)/drivers
42MESS_FORMATS = $(MESSOBJ)/formats
4342MESS_LAYOUT = $(MESSOBJ)/layout
4443MESS_MACHINE = $(MESSOBJ)/machine
4544MESS_VIDEO = $(MESSOBJ)/video
r21309r21310
5453   $(MAME_VIDEO) \
5554   $(MESS_AUDIO) \
5655   $(MESS_DRIVERS) \
57   $(MESS_FORMATS) \
5856   $(MESS_LAYOUT) \
5957   $(MESS_MACHINE) \
6058   $(MESS_VIDEO) \

Previous 199869 Revisions Next


© 1997-2024 The MAME Team