Previous 15994 Revisions Next

r3322 Wednesday 24th September, 2008 at 20:32:52 UTC by Wilbert Pol
[KIM1] Added proper support for .kim/.kim1 cassette images.
[src/mess]mess.mak
[src/mess/drivers]kim1.c
[src/mess/formats]kim1_cas.c* kim1_cas.h*

src/mess/mess.mak
r3321r3322
889889   $(MESS_MACHINE)/msx.o    \
890890
891891$(MESSOBJ)/kim1.a :    \
892   $(MESS_DRIVERS)/kim1.o
892   $(MESS_DRIVERS)/kim1.o   \
893   $(MESS_FORMATS)/kim1_cas.o
893894
894895$(MESSOBJ)/synertec.a :    \
895896   $(MESS_MACHINE)/sym1.o    \
src/mess/formats/kim1_cas.c
r0r3322
1#include "kim1_cas.h"
2
3#define SMPLO   -32768
4#define SMPHI   32767
5
6
7static int cas_size;
8
9
10INLINE int kim1_output_signal( INT16 *buffer, int sample_pos, int high )
11{
12   int sample_count, i, j;
13
14   sample_count = 0;
15
16   if ( high )
17   {
18      /* high frequency (~3600Hz) */
19      for ( i = 0; i < 9; i++ )
20      {
21         if ( buffer )
22         {
23            for ( j = 0; j < 6; j++ )
24               buffer[ sample_pos + sample_count + j ] = SMPHI;
25         }
26         sample_count += 6;
27
28         if ( buffer )
29         {
30            for ( j = 0; j < 6; j++ )
31               buffer[ sample_pos + sample_count + j ] = SMPLO;
32         }
33         sample_count += 6;
34      }
35   }
36   else
37   {
38      /* low frequency (~2400Hz) */
39      for ( i = 0; i < 6; i++ )
40      {
41         if ( buffer )
42         {
43            for ( j = 0; j < 9; j++ )
44               buffer[ sample_pos + sample_count + j ] = SMPHI;
45         }
46         sample_count += 9;
47
48         if ( buffer )
49         {
50            for ( j = 0; j < 9; j++ )
51               buffer[ sample_pos + sample_count + j ] = SMPLO;
52         }
53         sample_count += 9;
54      }
55   }
56
57   return sample_count;
58}
59
60
61INLINE int kim1_output_byte( INT16 *buffer, int sample_pos, UINT8 byte )
62{
63   int i;
64   int sample_count = 0;
65
66   for ( i = 0; i < 8; i++ )
67   {
68      sample_count += kim1_output_signal( buffer, sample_pos + sample_count, 1 );
69      sample_count += kim1_output_signal( buffer, sample_pos + sample_count, byte & 0x01 ? 0 : 1 );
70      sample_count += kim1_output_signal( buffer, sample_pos + sample_count, 0 );
71      byte >>= 1;
72   }
73   return sample_count;
74}
75
76
77static int kim1_handle_kim(INT16 *buffer, const UINT8 *casdata)
78{
79   static const UINT8 encoding[16] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 };
80   int   i, data_pos, sample_count;
81   UINT16 size, address, file_id, checksum;
82
83   if ( cas_size < 9 )   return -1;
84   if ( memcmp( casdata, "KIM1", 4 ) ) return -1;
85
86   address = casdata[4] | ( casdata[5] << 8 );
87   size = casdata[6] | ( casdata[7] << 8 );
88   file_id = casdata[8];
89
90   data_pos = 9;
91   sample_count = 0;
92   checksum = casdata[4] + casdata[5];
93
94   /* First output a sync header: 100 x 16h */
95   for ( i = 0; i < 100; i++ )
96      sample_count += kim1_output_byte( buffer, sample_count, 0x16 );
97
98   /* Output end of sync: 2Ah */
99   sample_count += kim1_output_byte( buffer, sample_count, 0x2A );
100
101   /* Output ID */
102   sample_count += kim1_output_byte( buffer, sample_count, encoding[ file_id >> 4 ] );
103   sample_count += kim1_output_byte( buffer, sample_count, encoding[ file_id & 0x0f ] );
104
105   /* Output starting address */
106   sample_count += kim1_output_byte( buffer, sample_count, encoding[ ( address & 0xff ) >> 4 ] );
107   sample_count += kim1_output_byte( buffer, sample_count, encoding[ address & 0x0f ] );
108   sample_count += kim1_output_byte( buffer, sample_count, encoding[ address >> 12 ] );
109   sample_count += kim1_output_byte( buffer, sample_count, encoding[ ( address >> 8 ) & 0x0f ] );
110
111   /* Output the data */
112   while( data_pos < cas_size && data_pos < ( size + 9 ) )
113   {
114      UINT8 data = casdata[data_pos];
115
116      sample_count += kim1_output_byte( buffer, sample_count, encoding[ data >> 4 ] );
117      sample_count += kim1_output_byte( buffer, sample_count, encoding[ data & 0x0f ] );
118      checksum += data;
119      data_pos++;
120   }
121
122   /* Output end of data marker: 2Fh */
123   sample_count += kim1_output_byte( buffer, sample_count, 0x2F );
124
125   /* Output checksum */
126   sample_count += kim1_output_byte( buffer, sample_count, encoding[ ( checksum & 0xff ) >> 4 ] );
127   sample_count += kim1_output_byte( buffer, sample_count, encoding[ checksum & 0x0f ] );
128   sample_count += kim1_output_byte( buffer, sample_count, encoding[ checksum >> 12 ] );
129   sample_count += kim1_output_byte( buffer, sample_count, encoding[ ( checksum >> 8 ) & 0x0f ] );
130
131   /* Output end of transmission marker: 2 x 04h */
132   sample_count += kim1_output_byte( buffer, sample_count, 0x04 );
133   sample_count += kim1_output_byte( buffer, sample_count, 0x04 );
134
135   return sample_count;
136}
137
138
139/*******************************************************************
140   Generate samples for the tape image
141********************************************************************/
142static int kim1_kim_fill_wave(INT16 *buffer, int sample_count, UINT8 *bytes)
143{
144   return kim1_handle_kim( buffer, bytes );
145}
146
147
148/*******************************************************************
149   Calculate the number of samples needed for this tape image
150********************************************************************/
151static int kim1_kim_to_wav_size(const UINT8 *casdata, int caslen)
152{
153   cas_size = caslen;
154
155   return kim1_handle_kim( NULL, casdata );
156}
157
158static const struct CassetteLegacyWaveFiller kim1_kim_legacy_fill_wave =
159{
160   kim1_kim_fill_wave,                  /* fill_wave */
161   -1,                              /* chunk_size */
162   0,                              /* chunk_samples */
163   kim1_kim_to_wav_size,               /* chunk_sample_calc */
164   44100,                           /* sample_frequency */
165   0,                              /* header_samples */
166   0                              /* trailer_samples */
167};
168
169
170static casserr_t kim1_kim_identify(cassette_image *cassette, struct CassetteOptions *opts)
171{
172   return cassette_legacy_identify(cassette, opts, &kim1_kim_legacy_fill_wave);
173}
174
175
176static casserr_t kim1_kim_load(cassette_image *cassette)
177{
178   return cassette_legacy_construct(cassette, &kim1_kim_legacy_fill_wave);
179}
180
181
182static const struct CassetteFormat kim1_kim_format =
183{
184   "kim,kim1",
185   kim1_kim_identify,
186   kim1_kim_load,
187   NULL
188};
189
190
191CASSETTE_FORMATLIST_START(kim1_cassette_formats)
192   CASSETTE_FORMAT(kim1_kim_format)
193CASSETTE_FORMATLIST_END
194
src/mess/formats/kim1_cas.h
r0r3322
1/*********************************************************************
2
3    kim1_cas.h
4
5    Format code for KIM-1 casette files.
6
7*********************************************************************/
8
9#ifndef __KIM1_CAS_H
10#define __KIM1_CAS_H
11
12#include "formats/cassimg.h"
13
14CASSETTE_FORMATLIST_EXTERN(kim1_cassette_formats);
15
16#endif /* __KIM1_CAS_H */
17
src/mess/drivers/kim1.c
r3321r3322
8282#include "driver.h"
8383#include "machine/6530miot.h"
8484#include "devices/cassette.h"
85#include "formats/kim1_cas.h"
8586#include "kim1.lh"
8687
8788
r3321r3322
311312}
312313
313314
315static const cassette_config kim1_cassette_config =
316{
317   kim1_cassette_formats,
318   NULL,
319   CASSETTE_STOPPED
320};
321
322
314323static MACHINE_DRIVER_START( kim1 )
315324   /* basic machine hardware */
316325   MDRV_CPU_ADD("main", M6502, 1000000)        /* 1 MHz */
r3321r3322
329338   MDRV_SOUND_ADD("dac", DAC, 0)
330339   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
331340
332   MDRV_CASSETTE_ADD( "cassette", default_cassette_config )
341   MDRV_CASSETTE_ADD( "cassette", kim1_cassette_config )
333342
334343   /* video */
335344   MDRV_DEFAULT_LAYOUT( layout_kim1 )
r3321r3322
343352ROM_END
344353
345354
346#ifdef UNUSED_FUNCTION
347static DEVICE_IMAGE_LOAD( kim1_cassette )
348{
349   const char magic[] = "KIM1";
350   char buff[4];
351   UINT16 addr, size;
352   UINT8 ident, *RAM = memory_region(image->machine, "main");
353
354   image_fread(image, buff, sizeof (buff));
355   if (memcmp(buff, magic, sizeof (buff)))
356   {
357      logerror("kim1_rom_load: magic '%s' not found\n", magic);
358      return INIT_FAIL;
359   }
360   image_fread(image, &addr, 2);
361   addr = LITTLE_ENDIANIZE_INT16(addr);
362   image_fread(image, &size, 2);
363   size = LITTLE_ENDIANIZE_INT16(size);
364   image_fread(image, &ident, 1);
365   logerror("kim1_rom_load: $%04X $%04X $%02X\n", addr, size, ident);
366   while (size-- > 0)
367      image_fread(image, &RAM[addr++], 1);
368   return INIT_PASS;
369}
370
371
372static void kim1_cassette_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
373{
374   switch(state)
375   {
376      /* --- the following bits of info are returned as 64-bit signed integers --- */
377      case MESS_DEVINFO_INT_TYPE:                        info->i = IO_CASSETTE; break;
378      case MESS_DEVINFO_INT_READABLE:                     info->i = 1; break;
379      case MESS_DEVINFO_INT_WRITEABLE:                  info->i = 0; break;
380      case MESS_DEVINFO_INT_CREATABLE:                  info->i = 0; break;
381      case MESS_DEVINFO_INT_COUNT:                     info->i = 1; break;
382      case MESS_DEVINFO_INT_RESET_ON_LOAD:               info->i = 1; break;
383
384      /* --- the following bits of info are returned as pointers to data or functions --- */
385      case MESS_DEVINFO_PTR_LOAD:                        info->load = DEVICE_IMAGE_LOAD_NAME(kim1_cassette); break;
386
387      /* --- the following bits of info are returned as NULL-terminated strings --- */
388      case MESS_DEVINFO_STR_FILE_EXTENSIONS:               strcpy(info->s = device_temp_str(), "kim1"); break;
389   }
390}
391
392
393static SYSTEM_CONFIG_START(kim1)
394   CONFIG_DEVICE(kim1_cassette_getinfo)
395SYSTEM_CONFIG_END
396#endif
397
398355/*    YEAR  NAME      PARENT    COMPAT  MACHINE   INPUT     INIT      CONFIG  COMPANY   FULLNAME */
399356COMP( 1975, kim1,     0,       0,      kim1,     kim1,    0,        0,     "MOS Technologies",  "KIM-1" , GAME_SUPPORTS_SAVE)

Previous 15994 Revisions Next


© 1998-2018 The MESS Team