Previous 199869 Revisions Next

r32917 Friday 24th October, 2014 at 04:10:24 UTC by Fabio Priuli
(MESS) spc1000: added support for tapes in .cas format [Fabio Priuli]

(MESS) spc1000: added emulation of joystick inputs [Fabio Priuli]

(MESS) added software list for Samsung spc1000 tapes [Fabio Priuli]

out of whatsnew: addition of joystick support made playable Space Invaders, Super Xevious, The Goonies and King's Valley.
[src/lib/formats]spc1000_cas.c
[src/mess/drivers]spc1000.c

trunk/src/lib/formats/spc1000_cas.c
r241428r241429
1010TAP: This is a series of 0x30 and 0x31 bytes, representing binary
1111     0 and 1. It includes the header and leaders.
1212
13CAS: This format has not been investigated yet.
13CAS: Files in this format consist of a 16 bytes header (SPC-1000.CASfmt )
14     followed by cassette bits packed together (each byte of a .cas file
15     are 8 bits, most significant bit first)
1416
1517STA: This format has not been investigated yet, but is assumed to
1618     be the save state of some other emulator.
1719
18IPL: This format has not been investigated yet.
20IPL: This seems a quickload format containing RAM dump, not a real tape
1921
2022********************************************************************/
2123
r241428r241429
5860   return samples;
5961}
6062
61static int spc1000_handle_cassette(INT16 *buffer, const UINT8 *bytes)
63static int spc1000_handle_tap(INT16 *buffer, const UINT8 *bytes)
6264{
6365   UINT32 sample_count = 0;
64   UINT32 i;
6566
6667   /* data */
67   for (i=0; i<spc1000_image_size; i++)
68      sample_count += spc1000_output_bit(buffer, sample_count, bytes[i]&1);
68   for (UINT32 i = 0; i < spc1000_image_size; i++)
69      sample_count += spc1000_output_bit(buffer, sample_count, bytes[i] & 1);
6970
7071   return sample_count;
7172}
7273
74static int spc1000_handle_cas(INT16 *buffer, const UINT8 *bytes)
75{
76   UINT32 sample_count = 0;
77   
78   /* data (skipping first 16 bytes, which is CAS header) */
79   for (UINT32 i = 0x10; i < spc1000_image_size; i++)
80      for (int j = 0; j < 8; j++)
81         sample_count += spc1000_output_bit(buffer, sample_count, (bytes[i] >> (7 - j)) & 1);
82   
83   return sample_count;
84}
7385
86
7487/*******************************************************************
7588   Generate samples for the tape image
7689********************************************************************/
7790
78static int spc1000_cassette_fill_wave(INT16 *buffer, int length, UINT8 *bytes)
91static int spc1000_tap_fill_wave(INT16 *buffer, int length, UINT8 *bytes)
7992{
80   return spc1000_handle_cassette(buffer, bytes);
93   return spc1000_handle_tap(buffer, bytes);
8194}
8295
96static int spc1000_cas_fill_wave(INT16 *buffer, int length, UINT8 *bytes)
97{
98   return spc1000_handle_cas(buffer, bytes);
99}
100
83101/*******************************************************************
84102   Calculate the number of samples needed for this tape image
85103********************************************************************/
86104
87static int spc1000_cassette_calculate_size_in_samples(const UINT8 *bytes, int length)
105static int spc1000_tap_calculate_size_in_samples(const UINT8 *bytes, int length)
88106{
89107   spc1000_image_size = length;
90108
91   return spc1000_handle_cassette(NULL, bytes);
109   return spc1000_handle_tap(NULL, bytes);
92110}
93111
94static const struct CassetteLegacyWaveFiller spc1000_legacy_fill_wave =
112static int spc1000_cas_calculate_size_in_samples(const UINT8 *bytes, int length)
95113{
96   spc1000_cassette_fill_wave,                 /* fill_wave */
114   spc1000_image_size = length;
115   
116   return spc1000_handle_cas(NULL, bytes);
117}
118
119
120/*******************************************************************
121   Formats
122 ********************************************************************/
123
124
125// TAP
126static const struct CassetteLegacyWaveFiller spc1000_tap_legacy_fill_wave =
127{
128   spc1000_tap_fill_wave,                 /* fill_wave */
97129   -1,                                     /* chunk_size */
98130   0,                                      /* chunk_samples */
99   spc1000_cassette_calculate_size_in_samples, /* chunk_sample_calc */
131   spc1000_tap_calculate_size_in_samples, /* chunk_sample_calc */
100132   SPC1000_WAV_FREQUENCY,                      /* sample_frequency */
101133   0,                                      /* header_samples */
102134   0                                       /* trailer_samples */
103135};
104136
105static casserr_t spc1000_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts)
137static casserr_t spc1000_tap_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts)
106138{
107   return cassette_legacy_identify(cassette, opts, &spc1000_legacy_fill_wave);
139   return cassette_legacy_identify(cassette, opts, &spc1000_tap_legacy_fill_wave);
108140}
109141
110static casserr_t spc1000_cassette_load(cassette_image *cassette)
142static casserr_t spc1000_tap_cassette_load(cassette_image *cassette)
111143{
112   return cassette_legacy_construct(cassette, &spc1000_legacy_fill_wave);
144   return cassette_legacy_construct(cassette, &spc1000_tap_legacy_fill_wave);
113145}
114146
115static const struct CassetteFormat spc1000_cassette_image_format =
147static const struct CassetteFormat spc1000_tap_cassette_image_format =
116148{
117149   "tap",
118   spc1000_cassette_identify,
119   spc1000_cassette_load,
150   spc1000_tap_cassette_identify,
151   spc1000_tap_cassette_load,
120152   NULL
121153};
122154
155
156// CAS
157static const struct CassetteLegacyWaveFiller spc1000_cas_legacy_fill_wave =
158{
159   spc1000_cas_fill_wave,                 /* fill_wave */
160   -1,                                     /* chunk_size */
161   0,                                      /* chunk_samples */
162   spc1000_cas_calculate_size_in_samples, /* chunk_sample_calc */
163   SPC1000_WAV_FREQUENCY,                      /* sample_frequency */
164   0,                                      /* header_samples */
165   0                                       /* trailer_samples */
166};
167
168static casserr_t spc1000_cas_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts)
169{
170   return cassette_legacy_identify(cassette, opts, &spc1000_cas_legacy_fill_wave);
171}
172
173static casserr_t spc1000_cas_cassette_load(cassette_image *cassette)
174{
175   return cassette_legacy_construct(cassette, &spc1000_cas_legacy_fill_wave);
176}
177
178static const struct CassetteFormat spc1000_cas_cassette_image_format =
179{
180   "cas",
181   spc1000_cas_cassette_identify,
182   spc1000_cas_cassette_load,
183   NULL
184};
185
186
187
123188CASSETTE_FORMATLIST_START(spc1000_cassette_formats)
124   CASSETTE_FORMAT(spc1000_cassette_image_format)
189   CASSETTE_FORMAT(spc1000_tap_cassette_image_format)
190   CASSETTE_FORMAT(spc1000_cas_cassette_image_format)
125191CASSETTE_FORMATLIST_END
trunk/src/mess/drivers/spc1000.c
r241428r241429
5454      , m_pio(*this, "d8255_master")
5555      , m_ram(*this, RAM_TAG)
5656      , m_cass(*this, "cassette")
57      , m_io_joy(*this, "JOY")
5758   {}
5859
5960   DECLARE_WRITE8_MEMBER(spc1000_iplk_w);
r241428r241429
6970   DECLARE_WRITE8_MEMBER(fdc_8255_b_w);
7071   DECLARE_READ8_MEMBER(fdc_8255_c_r);
7172   DECLARE_WRITE8_MEMBER(fdc_8255_c_w);
72   DECLARE_READ8_MEMBER( upd765_tc_r );
73   DECLARE_WRITE8_MEMBER( fdc_control_w );
73   DECLARE_READ8_MEMBER(upd765_tc_r);
74   DECLARE_WRITE8_MEMBER(fdc_control_w);
7475   MC6847_GET_CHARROM_MEMBER(get_char_rom)
7576   {
7677      return m_p_videoram[0x1000 + (ch & 0x7f) * 16 + line];
r241428r241429
8283   UINT8 m_GMODE;
8384   UINT16 m_page;
8485   UINT8 *m_work_ram;
86   virtual void machine_start();
8587   virtual void machine_reset();
8688   required_device<mc6847_base_device> m_vdg;
8789   required_device<cpu_device> m_maincpu;
r241428r241429
9092   required_device<i8255_device> m_pio;
9193   required_device<ram_device> m_ram;
9294   required_device<cassette_image_device> m_cass;
95   required_ioport m_io_joy;
9396
9497   floppy_image_device *m_fd0;
9598   floppy_image_device *m_fd1;
r241428r241429
110113
111114static ADDRESS_MAP_START(spc1000_mem, AS_PROGRAM, 8, spc1000_state )
112115   ADDRESS_MAP_UNMAP_HIGH
113   AM_RANGE( 0x0000, 0x7fff ) AM_READ_BANK("bank1") AM_WRITE_BANK("bank2")
114   AM_RANGE( 0x8000, 0xffff ) AM_READ_BANK("bank3") AM_WRITE_BANK("bank4")
116   AM_RANGE(0x0000, 0x7fff) AM_READ_BANK("bank1") AM_WRITE_BANK("bank2")
117   AM_RANGE(0x8000, 0xffff) AM_READ_BANK("bank3") AM_WRITE_BANK("bank4")
115118ADDRESS_MAP_END
116119
117120WRITE8_MEMBER(spc1000_state::spc1000_iplk_w)
118121{
119122   m_IPLK = m_IPLK ? 0 : 1;
120   if (m_IPLK == 1) {
121      UINT8 *mem = memregion("maincpu")->base();
122      membank("bank1")->set_base(mem);
123      membank("bank3")->set_base(mem);
124   } else {
125      UINT8 *ram = m_ram->pointer();
126      membank("bank1")->set_base(ram);
127      membank("bank3")->set_base(ram + 0x8000);
128   }
123   membank("bank1")->set_entry(m_IPLK);
124   membank("bank3")->set_entry(m_IPLK);
129125}
130126
131127READ8_MEMBER(spc1000_state::spc1000_iplk_r)
132128{
133129   m_IPLK = m_IPLK ? 0 : 1;
134   if (m_IPLK == 1) {
135      UINT8 *mem = memregion("maincpu")->base();
136      membank("bank1")->set_base(mem);
137      membank("bank3")->set_base(mem);
138   } else {
139      UINT8 *ram = m_ram->pointer();
140      membank("bank1")->set_base(ram);
141      membank("bank3")->set_base(ram + 0x8000);
142   }
130   membank("bank1")->set_entry(m_IPLK);
131   membank("bank3")->set_entry(m_IPLK);
132
143133   return 0;
144134}
145135
r241428r241429
350340      PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c)
351341      PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0e)
352342      PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
343
344   PORT_START("JOY")
345   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1)
346   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
347   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
348   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
349   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
350   PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_UNUSED) // Button 2?
351   PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED) // Cassette related
353352INPUT_PORTS_END
354353
355354
356void spc1000_state::machine_reset()
355void spc1000_state::machine_start()
357356{
358   address_space &space = m_maincpu->space(AS_PROGRAM);
359357   UINT8 *mem = memregion("maincpu")->base();
360358   UINT8 *ram = m_ram->pointer();
361359
362   space.install_read_bank(0x0000, 0x7fff, "bank1");
363   space.install_read_bank(0x8000, 0xffff, "bank3");
360   // configure and intialize banks 1 & 3 (read banks)
361   membank("bank1")->configure_entry(0, ram);
362   membank("bank1")->configure_entry(1, mem);
363   membank("bank3")->configure_entry(0, ram + 0x8000);
364   membank("bank3")->configure_entry(1, mem);
365   membank("bank1")->set_entry(1);
366   membank("bank3")->set_entry(1);
364367
365   space.install_write_bank(0x0000, 0x7fff, "bank2");
366   space.install_write_bank(0x8000, 0xffff, "bank4");
367
368   membank("bank1")->set_base(mem);
368   // intialize banks 2 & 4 (write banks)
369369   membank("bank2")->set_base(ram);
370   membank("bank3")->set_base(mem);
371370   membank("bank4")->set_base(ram + 0x8000);
371}
372372
373void spc1000_state::machine_reset()
374{
375
373376   m_work_ram = auto_alloc_array_clear(machine(), UINT8, 0x10000);
374377   m_fdccpu->set_input_line_vector(0, 0);
375378
r241428r241429
407410
408411READ8_MEMBER( spc1000_state::porta_r )
409412{
410   UINT8 data = 0;
413   UINT8 data = 0x3f;
411414   data |= (m_cass->input() > 0.0038) ? 0x80 : 0;
412415   data |= ((m_cass->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) ? 0x00 : 0x40;
413
416   data &= ~(m_io_joy->read() & 0x3f);
417   
414418   return data;
415419}
416420
r241428r241429
491495   MCFG_CASSETTE_FORMATS(spc1000_cassette_formats)
492496   MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED)
493497
498   MCFG_SOFTWARE_LIST_ADD("cass_list", "spc1000_cass")
499
494500   /* internal ram */
495501   MCFG_RAM_ADD(RAM_TAG)
496502   MCFG_RAM_DEFAULT_SIZE("64K")


Previous 199869 Revisions Next


© 1997-2024 The MAME Team