Previous 199869 Revisions Next

r33796 Wednesday 10th December, 2014 at 10:15:19 UTC by Curt Coder
(MESS) c8050: Floppy WIP. (nw)
[src/emu/bus]bus.mak
[src/emu/bus/ieee488]c2040fdc.c c2040fdc.h c8050fdc.c* c8050fdc.h*

trunk/src/emu/bus/bus.mak
r242307r242308
403403BUSOBJS += $(BUSOBJ)/ieee488/c2040.o
404404BUSOBJS += $(BUSOBJ)/ieee488/c2040fdc.o
405405BUSOBJS += $(BUSOBJ)/ieee488/c8050.o
406BUSOBJS += $(BUSOBJ)/ieee488/c8050fdc.o
406407BUSOBJS += $(BUSOBJ)/ieee488/c8280.o
407408BUSOBJS += $(BUSOBJ)/ieee488/d9060.o
408409BUSOBJS += $(BUSOBJ)/ieee488/softbox.o
trunk/src/emu/bus/ieee488/c2040fdc.c
r242307r242308
99
1010**********************************************************************/
1111
12/*
13
14    TODO:
15
16    - writing starts in the middle of a byte
17    - 8050 PLL
18
19*/
20
2112#include "c2040fdc.h"
2213
2314
r242307r242308
3526//**************************************************************************
3627
3728const device_type C2040_FDC = &device_creator<c2040_fdc_t>;
38const device_type C8050_FDC = &device_creator<c8050_fdc_t>;
3929
4030
4131//-------------------------------------------------
r242307r242308
6757//  c2040_fdc_t - constructor
6858//-------------------------------------------------
6959
70c2040_fdc_t::c2040_fdc_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
71   device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
72   m_write_sync(*this),
73   m_write_ready(*this),
74   m_write_error(*this),
75   m_gcr_rom(*this, "gcr"),
76   m_floppy0(NULL),
77   m_floppy1(NULL),
78   m_mtr0(1),
79   m_mtr1(1),
80   m_stp0(0),
81   m_stp1(0),
82   m_ds(0),
83   m_drv_sel(0),
84   m_mode_sel(0),
85   m_rw_sel(0),
86   m_period(attotime::from_hz(clock))
87{
88   cur_live.tm = attotime::never;
89   cur_live.state = IDLE;
90   cur_live.next_state = -1;
91   cur_live.write_position = 0;
92   cur_live.write_start_time = attotime::never;
93}
94
9560c2040_fdc_t::c2040_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
9661   device_t(mconfig, C2040_FDC, "C2040 FDC", tag, owner, clock, "c2040fdc", __FILE__),
9762   m_write_sync(*this),
r242307r242308
11883   cur_live.drv_sel = m_drv_sel;
11984}
12085
121c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
122   c2040_fdc_t(mconfig, C8050_FDC, "C8050 FDC", tag, owner, clock, "c8050fdc", __FILE__) { }
12386
12487
125
12688//-------------------------------------------------
12789//  device_start - device-specific startup
12890//-------------------------------------------------
r242307r242308
635597   m_floppy0 = floppy0;
636598   m_floppy1 = floppy1;
637599}
638
639void c8050_fdc_t::live_start()
640{
641   cur_live.tm = machine().time();
642   cur_live.state = RUNNING;
643   cur_live.next_state = -1;
644
645   cur_live.shift_reg = 0;
646   cur_live.shift_reg_write = 0;
647   cur_live.cycle_counter = 0;
648   cur_live.cell_counter = 0;
649   cur_live.bit_counter = 0;
650   cur_live.ds = m_ds;
651   cur_live.drv_sel = m_drv_sel;
652   cur_live.mode_sel = m_mode_sel;
653   cur_live.rw_sel = m_rw_sel;
654   cur_live.pi = m_pi;
655
656   pll_reset(cur_live.tm, attotime::from_double(0));
657   checkpoint_live = cur_live;
658   pll_save_checkpoint();
659
660   live_run();
661}
662
663void c8050_fdc_t::pll_reset(const attotime &when, const attotime clock)
664{
665   cur_pll.reset(when);
666   cur_pll.set_clock(clock);
667}
668
669void c8050_fdc_t::pll_save_checkpoint()
670{
671   checkpoint_pll = cur_pll;
672}
673
674void c8050_fdc_t::pll_retrieve_checkpoint()
675{
676   cur_pll = checkpoint_pll;
677}
678
679void c8050_fdc_t::checkpoint()
680{
681   checkpoint_live = cur_live;
682   pll_save_checkpoint();
683}
684
685void c8050_fdc_t::rollback()
686{
687   cur_live = checkpoint_live;
688   pll_retrieve_checkpoint();
689}
690
691void c8050_fdc_t::live_run(const attotime &limit)
692{
693   if(cur_live.state == IDLE || cur_live.next_state != -1)
694      return;
695
696   for(;;) {
697      switch(cur_live.state) {
698      case RUNNING: {
699         bool syncpoint = false;
700
701         if (cur_live.tm > limit)
702            return;
703
704         int bit = get_next_bit(cur_live.tm, limit);
705         if(bit < 0)
706            return;
707
708         if (syncpoint) {
709            commit(cur_live.tm);
710
711            cur_live.tm += m_period;
712            live_delay(RUNNING_SYNCPOINT);
713            return;
714         }
715
716         cur_live.tm += m_period;
717         break;
718      }
719
720      case RUNNING_SYNCPOINT: {
721         m_write_ready(cur_live.ready);
722         m_write_sync(cur_live.sync);
723         m_write_error(cur_live.error);
724
725         cur_live.state = RUNNING;
726         checkpoint();
727         break;
728      }
729      }
730   }
731}
732
733int c8050_fdc_t::get_next_bit(attotime &tm, const attotime &limit)
734{
735   return cur_pll.get_next_bit(tm, get_floppy(), limit);
736}
737
738void c8050_fdc_t::stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp)
739{
740   if (mtr) return;
741
742   int tracks = 0;
743
744   switch (old_stp)
745   {
746   case 0: if (stp == 1) tracks++; else if (stp == 2) tracks--; break;
747   case 1: if (stp == 3) tracks++; else if (stp == 0) tracks--; break;
748   case 2: if (stp == 0) tracks++; else if (stp == 3) tracks--; break;
749   case 3: if (stp == 2) tracks++; else if (stp == 1) tracks--; break;
750   }
751
752   if (tracks == -1)
753   {
754      floppy->dir_w(1);
755      floppy->stp_w(1);
756      floppy->stp_w(0);
757   }
758   else if (tracks == 1)
759   {
760      floppy->dir_w(0);
761      floppy->stp_w(1);
762      floppy->stp_w(0);
763   }
764
765   old_stp = stp;
766}
767
768WRITE_LINE_MEMBER( c8050_fdc_t::odd_hd_w )
769{
770   if (m_odd_hd != state)
771   {
772      live_sync();
773      m_odd_hd = cur_live.odd_hd = state;
774      if (LOG) logerror("%s ODD HD %u\n", machine().time().as_string(), state);
775      m_floppy0->ss_w(!state);
776      if (m_floppy1) m_floppy1->ss_w(!state);
777      checkpoint();
778      live_run();
779   }
780}
781
782WRITE_LINE_MEMBER( c8050_fdc_t::pull_sync_w )
783{
784   // TODO
785   if (LOG) logerror("%s PULL SYNC %u\n", machine().time().as_string(), state);
786}
trunk/src/emu/bus/ieee488/c2040fdc.h
r242307r242308
1818#include "formats/d64_dsk.h"
1919#include "formats/d67_dsk.h"
2020#include "formats/g64_dsk.h"
21#include "formats/d80_dsk.h"
22#include "formats/d82_dsk.h"
2321#include "imagedev/floppy.h"
24#include "machine/fdc_pll.h"
2522
2623
2724
r242307r242308
5047{
5148public:
5249   // construction/destruction
53   c2040_fdc_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
5450   c2040_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
5551
5652   template<class _Object> static devcb_base &set_sync_wr_callback(device_t &device, _Object object) { return downcast<c2040_fdc_t &>(device).m_write_sync.set_callback(object); }
r242307r242308
6864
6965   DECLARE_READ_LINE_MEMBER( wps_r ) { return checkpoint_live.drv_sel ? m_floppy1->wpt_r() : m_floppy0->wpt_r(); }
7066   DECLARE_READ_LINE_MEMBER( sync_r ) { return checkpoint_live.sync; }
71   DECLARE_READ_LINE_MEMBER( ready_r ) { return checkpoint_live.ready; }
72   DECLARE_READ_LINE_MEMBER( error_r ) { return checkpoint_live.error; }
7367
7468   void stp0_w(int stp);
7569   void stp1_w(int stp);
r242307r242308
147141   emu_timer *t_gen;
148142
149143   floppy_image_device* get_floppy();
150   virtual void live_start();
151   virtual void checkpoint();
152   virtual void rollback();
144
145   void live_start();
146   void checkpoint();
147   void rollback();
153148   bool write_next_bit(bool bit, const attotime &limit);
154149   void start_writing(const attotime &tm);
155150   void commit(const attotime &tm);
r242307r242308
157152   void live_delay(int state);
158153   void live_sync();
159154   void live_abort();
160   virtual void live_run(const attotime &limit = attotime::never);
155   void live_run(const attotime &limit = attotime::never);
161156   void get_next_edge(const attotime &when);
162   virtual int get_next_bit(attotime &tm, const attotime &limit);
157   int get_next_bit(attotime &tm, const attotime &limit);
163158};
164159
165160
166// ======================> c8050_fdc_t
167
168class c8050_fdc_t :  public c2040_fdc_t
169{
170public:
171   // construction/destruction
172   c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
173
174   DECLARE_WRITE_LINE_MEMBER( odd_hd_w );
175   DECLARE_WRITE_LINE_MEMBER( pull_sync_w );
176
177protected:
178   fdc_pll_t cur_pll, checkpoint_pll;
179
180   void stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp);
181
182   virtual void live_start();
183   virtual void checkpoint();
184   virtual void rollback();
185   void pll_reset(const attotime &when, const attotime clock);
186   void pll_save_checkpoint();
187   void pll_retrieve_checkpoint();
188   virtual void live_run(const attotime &limit = attotime::never);
189   virtual int get_next_bit(attotime &tm, const attotime &limit);
190};
191
192
193
194161// device type definition
195162extern const device_type C2040_FDC;
196extern const device_type C8050_FDC;
197163
198164
199165
trunk/src/emu/bus/ieee488/c8050fdc.c
r0r242308
1// license:BSD-3-Clause
2// copyright-holders:Curt Coder
3/**********************************************************************
4
5    Commodore 8050 floppy disk controller emulation
6
7    Copyright MESS Team.
8    Visit http://mamedev.org for licensing and usage restrictions.
9
10**********************************************************************/
11
12#include "c8050fdc.h"
13
14
15
16//**************************************************************************
17//  MACROS / CONSTANTS
18//**************************************************************************
19
20#define LOG 0
21
22
23
24//**************************************************************************
25//  DEVICE DEFINITIONS
26//**************************************************************************
27
28const device_type C8050_FDC = &device_creator<c8050_fdc_t>;
29
30
31//-------------------------------------------------
32//  ROM( c8050_fdc )
33//-------------------------------------------------
34
35ROM_START( c8050_fdc )
36   ROM_REGION( 0x800, "gcr", 0)
37   ROM_LOAD( "901467.uk6", 0x000, 0x800, CRC(a23337eb) SHA1(97df576397608455616331f8e837cb3404363fa2) )
38ROM_END
39
40
41//-------------------------------------------------
42//  rom_region - device-specific ROM region
43//-------------------------------------------------
44
45const rom_entry *c8050_fdc_t::device_rom_region() const
46{
47   return ROM_NAME( c8050_fdc );
48}
49
50
51
52//**************************************************************************
53//  LIVE DEVICE
54//**************************************************************************
55
56//-------------------------------------------------
57//  c8050_fdc_t - constructor
58//-------------------------------------------------
59
60c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
61   device_t(mconfig, C8050_FDC, "C8050 FDC", tag, owner, clock, "c8050fdc", __FILE__),
62   m_write_sync(*this),
63   m_write_ready(*this),
64   m_write_error(*this),
65   m_gcr_rom(*this, "gcr"),
66   m_floppy0(NULL),
67   m_floppy1(NULL),
68   m_mtr0(1),
69   m_mtr1(1),
70   m_stp0(0),
71   m_stp1(0),
72   m_ds(0),
73   m_drv_sel(0),
74   m_mode_sel(0),
75   m_rw_sel(0),
76   m_period(attotime::from_hz(clock))
77{
78   cur_live.tm = attotime::never;
79   cur_live.state = IDLE;
80   cur_live.next_state = -1;
81   cur_live.drv_sel = m_drv_sel;
82}
83
84
85
86//-------------------------------------------------
87//  device_start - device-specific startup
88//-------------------------------------------------
89
90void c8050_fdc_t::device_start()
91{
92   // resolve callbacks
93   m_write_sync.resolve_safe();
94   m_write_ready.resolve_safe();
95   m_write_error.resolve_safe();
96
97   // allocate timer
98   t_gen = timer_alloc(0);
99
100   // register for state saving
101   save_item(NAME(m_mtr0));
102   save_item(NAME(m_mtr1));
103   save_item(NAME(m_stp0));
104   save_item(NAME(m_stp1));
105   save_item(NAME(m_ds));
106   save_item(NAME(m_drv_sel));
107   save_item(NAME(m_mode_sel));
108   save_item(NAME(m_rw_sel));
109}
110
111
112//-------------------------------------------------
113//  device_reset - device-specific reset
114//-------------------------------------------------
115
116void c8050_fdc_t::device_reset()
117{
118   live_abort();
119}
120
121
122//-------------------------------------------------
123//  device_timer - handler timer events
124//-------------------------------------------------
125
126void c8050_fdc_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
127{
128   live_sync();
129   live_run();
130}
131
132floppy_image_device* c8050_fdc_t::get_floppy()
133{
134   return cur_live.drv_sel ? m_floppy1 : m_floppy0;
135}
136
137void c8050_fdc_t::stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp)
138{
139   if (mtr) return;
140
141   int tracks = 0;
142
143   switch (old_stp)
144   {
145   case 0: if (stp == 1) tracks++; else if (stp == 2) tracks--; break;
146   case 1: if (stp == 3) tracks++; else if (stp == 0) tracks--; break;
147   case 2: if (stp == 0) tracks++; else if (stp == 3) tracks--; break;
148   case 3: if (stp == 2) tracks++; else if (stp == 1) tracks--; break;
149   }
150
151   if (tracks == -1)
152   {
153      floppy->dir_w(1);
154      floppy->stp_w(1);
155      floppy->stp_w(0);
156   }
157   else if (tracks == 1)
158   {
159      floppy->dir_w(0);
160      floppy->stp_w(1);
161      floppy->stp_w(0);
162   }
163
164   old_stp = stp;
165}
166
167void c8050_fdc_t::stp0_w(int stp)
168{
169   if (m_stp0 != stp)
170   {
171      live_sync();
172      this->stp_w(m_floppy0, m_mtr0, m_stp0, stp);
173      checkpoint();
174      live_run();
175   }
176}
177
178void c8050_fdc_t::stp1_w(int stp)
179{
180   if (m_stp1 != stp)
181   {
182      live_sync();
183      if (m_floppy1) this->stp_w(m_floppy1, m_mtr1, m_stp1, stp);
184      checkpoint();
185      live_run();
186   }
187}
188
189void c8050_fdc_t::ds_w(int ds)
190{
191   if (m_ds != ds)
192   {
193      live_sync();
194      m_ds = cur_live.ds = ds;
195      checkpoint();
196      live_run();
197   }
198}
199
200void c8050_fdc_t::set_floppy(floppy_image_device *floppy0, floppy_image_device *floppy1)
201{
202   m_floppy0 = floppy0;
203   m_floppy1 = floppy1;
204}
205
206void c8050_fdc_t::live_start()
207{
208   cur_live.tm = machine().time();
209   cur_live.state = RUNNING;
210   cur_live.next_state = -1;
211
212   cur_live.shift_reg = 0;
213   cur_live.shift_reg_write = 0;
214   cur_live.cycle_counter = 0;
215   cur_live.cell_counter = 0;
216   cur_live.bit_counter = 0;
217   cur_live.ds = m_ds;
218   cur_live.drv_sel = m_drv_sel;
219   cur_live.mode_sel = m_mode_sel;
220   cur_live.rw_sel = m_rw_sel;
221   cur_live.pi = m_pi;
222
223   pll_reset(cur_live.tm, attotime::from_double(0));
224   checkpoint_live = cur_live;
225   pll_save_checkpoint();
226
227   live_run();
228}
229
230void c8050_fdc_t::pll_reset(const attotime &when, const attotime clock)
231{
232   cur_pll.reset(when);
233   cur_pll.set_clock(clock);
234}
235
236void c8050_fdc_t::pll_start_writing(const attotime &tm)
237{
238   cur_pll.start_writing(tm);
239}
240
241void c8050_fdc_t::pll_commit(floppy_image_device *floppy, const attotime &tm)
242{
243   cur_pll.commit(floppy, tm);
244}
245
246void c8050_fdc_t::pll_stop_writing(floppy_image_device *floppy, const attotime &tm)
247{
248   cur_pll.stop_writing(floppy, tm);
249}
250
251void c8050_fdc_t::pll_save_checkpoint()
252{
253   checkpoint_pll = cur_pll;
254}
255
256void c8050_fdc_t::pll_retrieve_checkpoint()
257{
258   cur_pll = checkpoint_pll;
259}
260
261int c8050_fdc_t::pll_get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit)
262{
263   return cur_pll.get_next_bit(tm, floppy, limit);
264}
265
266bool c8050_fdc_t::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit)
267{
268   return cur_pll.write_next_bit_prev_cell(bit, tm, floppy, limit);
269}
270
271void c8050_fdc_t::checkpoint()
272{
273   pll_commit(get_floppy(), cur_live.tm);
274   checkpoint_live = cur_live;
275   pll_save_checkpoint();
276}
277
278void c8050_fdc_t::rollback()
279{
280   cur_live = checkpoint_live;
281   pll_retrieve_checkpoint();
282}
283
284void c8050_fdc_t::live_sync()
285{
286   if(!cur_live.tm.is_never()) {
287      if(cur_live.tm > machine().time()) {
288         rollback();
289         live_run(machine().time());
290         pll_commit(get_floppy(), cur_live.tm);
291      } else {
292         pll_commit(get_floppy(), cur_live.tm);
293         if(cur_live.next_state != -1) {
294            cur_live.state = cur_live.next_state;
295            cur_live.next_state = -1;
296         }
297         if(cur_live.state == IDLE) {
298            pll_stop_writing(get_floppy(), cur_live.tm);
299            cur_live.tm = attotime::never;
300         }
301      }
302      cur_live.next_state = -1;
303      checkpoint();
304   }
305}
306
307void c8050_fdc_t::live_abort()
308{
309   if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
310      rollback();
311      live_run(machine().time());
312   }
313
314   pll_stop_writing(get_floppy(), cur_live.tm);
315
316   cur_live.tm = attotime::never;
317   cur_live.state = IDLE;
318   cur_live.next_state = -1;
319
320   cur_live.ready = 1;
321   cur_live.sync = 1;
322   cur_live.error = 1;
323}
324
325
326void c8050_fdc_t::live_run(const attotime &limit)
327{
328   if(cur_live.state == IDLE || cur_live.next_state != -1)
329      return;
330
331   for(;;) {
332      switch(cur_live.state) {
333      case RUNNING: {
334         bool syncpoint = false;
335
336         if (cur_live.tm > limit)
337            return;
338
339         int bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit);
340         if(bit < 0)
341            return;
342
343         if (syncpoint) {
344            live_delay(RUNNING_SYNCPOINT);
345            return;
346         }
347         break;
348      }
349
350      case RUNNING_SYNCPOINT: {
351         m_write_ready(cur_live.ready);
352         m_write_sync(cur_live.sync);
353         m_write_error(cur_live.error);
354
355         cur_live.state = RUNNING;
356         checkpoint();
357         break;
358      }
359      }
360   }
361}
362
363READ8_MEMBER( c8050_fdc_t::read )
364{
365   UINT8 e = checkpoint_live.e;
366   offs_t i = checkpoint_live.i;
367
368   UINT8 data = (BIT(e, 6) << 7) | (BIT(i, 7) << 6) | (e & 0x33) | (BIT(e, 2) << 3) | (i & 0x04);
369
370   if (LOG) logerror("%s VIA reads data %02x (%03x)\n", machine().time().as_string(), data, checkpoint_live.shift_reg);
371
372   return data;
373}
374
375WRITE8_MEMBER( c8050_fdc_t::write )
376{
377   if (m_pi != data)
378   {
379      live_sync();
380      m_pi = cur_live.pi = data;
381      checkpoint();
382      if (LOG) logerror("%s PI %02x\n", machine().time().as_string(), data);
383      live_run();
384   }
385}
386
387WRITE_LINE_MEMBER( c8050_fdc_t::drv_sel_w )
388{
389   if (m_drv_sel != state)
390   {
391      live_sync();
392      m_drv_sel = cur_live.drv_sel = state;
393      checkpoint();
394      if (LOG) logerror("%s DRV SEL %u\n", machine().time().as_string(), state);
395      live_run();
396   }
397}
398
399WRITE_LINE_MEMBER( c8050_fdc_t::mode_sel_w )
400{
401   if (m_mode_sel != state)
402   {
403      live_sync();
404      m_mode_sel = cur_live.mode_sel = state;
405      checkpoint();
406      if (LOG) logerror("%s MODE SEL %u\n", machine().time().as_string(), state);
407      live_run();
408   }
409}
410
411WRITE_LINE_MEMBER( c8050_fdc_t::rw_sel_w )
412{
413   if (m_rw_sel != state)
414   {
415      live_sync();
416      m_rw_sel = cur_live.rw_sel = state;
417      checkpoint();
418      if (LOG) logerror("%s RW SEL %u\n", machine().time().as_string(), state);
419      if (m_rw_sel) {
420         pll_stop_writing(get_floppy(), machine().time());
421      } else {
422         pll_start_writing(machine().time());
423      }
424      live_run();
425   }
426}
427
428WRITE_LINE_MEMBER( c8050_fdc_t::mtr0_w )
429{
430   if (m_mtr0 != state)
431   {
432      live_sync();
433      m_mtr0 = state;
434      if (LOG) logerror("%s MTR0 %u\n", machine().time().as_string(), state);
435      m_floppy0->mon_w(state);
436      checkpoint();
437
438      if (!m_mtr0 || !m_mtr1) {
439         if(cur_live.state == IDLE) {
440            live_start();
441         }
442      } else {
443         live_abort();
444      }
445
446      live_run();
447   }
448}
449
450WRITE_LINE_MEMBER( c8050_fdc_t::mtr1_w )
451{
452   if (m_mtr1 != state)
453   {
454      live_sync();
455      m_mtr1 = state;
456      if (LOG) logerror("%s MTR1 %u\n", machine().time().as_string(), state);
457      if (m_floppy1) m_floppy1->mon_w(state);
458      checkpoint();
459
460      if (!m_mtr0 || !m_mtr1) {
461         if(cur_live.state == IDLE) {
462            live_start();
463         }
464      } else {
465         live_abort();
466      }
467
468      live_run();
469   }
470}
471
472WRITE_LINE_MEMBER( c8050_fdc_t::odd_hd_w )
473{
474   if (m_odd_hd != state)
475   {
476      live_sync();
477      m_odd_hd = cur_live.odd_hd = state;
478      if (LOG) logerror("%s ODD HD %u\n", machine().time().as_string(), state);
479      m_floppy0->ss_w(!state);
480      if (m_floppy1) m_floppy1->ss_w(!state);
481      checkpoint();
482      live_run();
483   }
484}
485
486WRITE_LINE_MEMBER( c8050_fdc_t::pull_sync_w )
487{
488   // TODO
489   if (LOG) logerror("%s PULL SYNC %u\n", machine().time().as_string(), state);
490}
trunk/src/emu/bus/ieee488/c8050fdc.h
r0r242308
1// license:BSD-3-Clause
2// copyright-holders:Curt Coder
3/**********************************************************************
4
5    Commodore 8050 floppy disk controller emulation
6
7    Copyright MESS Team.
8    Visit http://mamedev.org for licensing and usage restrictions.
9
10**********************************************************************/
11
12#pragma once
13
14#ifndef __C8050_FLOPPY__
15#define __C8050_FLOPPY__
16
17#include "emu.h"
18#include "formats/d80_dsk.h"
19#include "formats/d82_dsk.h"
20#include "imagedev/floppy.h"
21#include "machine/fdc_pll.h"
22
23
24
25//**************************************************************************
26//  INTERFACE CONFIGURATION MACROS
27//**************************************************************************
28
29#define MCFG_C8050_SYNC_CALLBACK(_write) \
30   devcb = &c8050_fdc_t::set_sync_wr_callback(*device, DEVCB_##_write);
31
32#define MCFG_C8050_READY_CALLBACK(_write) \
33   devcb = &c8050_fdc_t::set_ready_wr_callback(*device, DEVCB_##_write);
34
35#define MCFG_C8050_ERROR_CALLBACK(_write) \
36   devcb = &c8050_fdc_t::set_error_wr_callback(*device, DEVCB_##_write);
37
38
39
40//**************************************************************************
41//  TYPE DEFINITIONS
42//**************************************************************************
43
44// ======================> c8050_fdc_t
45
46class c8050_fdc_t :  public device_t
47{
48public:
49   // construction/destruction
50   c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
51
52   template<class _Object> static devcb_base &set_sync_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_sync.set_callback(object); }
53   template<class _Object> static devcb_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_ready.set_callback(object); }
54   template<class _Object> static devcb_base &set_error_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_error.set_callback(object); }
55
56   DECLARE_READ8_MEMBER( read );
57   DECLARE_WRITE8_MEMBER( write );
58
59   DECLARE_WRITE_LINE_MEMBER( drv_sel_w );
60   DECLARE_WRITE_LINE_MEMBER( mode_sel_w );
61   DECLARE_WRITE_LINE_MEMBER( rw_sel_w );
62   DECLARE_WRITE_LINE_MEMBER( mtr0_w );
63   DECLARE_WRITE_LINE_MEMBER( mtr1_w );
64   DECLARE_WRITE_LINE_MEMBER( odd_hd_w );
65   DECLARE_WRITE_LINE_MEMBER( pull_sync_w );
66
67   DECLARE_READ_LINE_MEMBER( wps_r ) { return checkpoint_live.drv_sel ? m_floppy1->wpt_r() : m_floppy0->wpt_r(); }
68   DECLARE_READ_LINE_MEMBER( sync_r ) { return checkpoint_live.sync; }
69
70   void stp0_w(int stp);
71   void stp1_w(int stp);
72   void ds_w(int ds);
73
74   void set_floppy(floppy_image_device *floppy0, floppy_image_device *floppy1);
75
76protected:
77   // device-level overrides
78   virtual void device_start();
79   virtual void device_reset();
80   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
81
82   // optional information overrides
83   virtual const rom_entry *device_rom_region() const;
84
85   void stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp);
86
87   enum {
88      IDLE,
89      RUNNING,
90      RUNNING_SYNCPOINT
91   };
92
93   struct live_info {
94      attotime tm;
95      int state, next_state;
96      int sync;
97      int ready;
98      int error;
99      int ds;
100      int drv_sel;
101      int mode_sel;
102      int rw_sel;
103      int odd_hd;
104
105      attotime edge;
106      UINT16 shift_reg;
107      int cycle_counter;
108      int cell_counter;
109      int bit_counter;
110      UINT8 e;
111      offs_t i;
112
113      UINT8 pi;
114      UINT16 shift_reg_write;
115   };
116
117   devcb_write_line m_write_sync;
118   devcb_write_line m_write_ready;
119   devcb_write_line m_write_error;
120
121   required_memory_region m_gcr_rom;
122
123   floppy_image_device *m_floppy0;
124   floppy_image_device *m_floppy1;
125
126   int m_mtr0;
127   int m_mtr1;
128   int m_stp0;
129   int m_stp1;
130   int m_ds;
131   int m_drv_sel;
132   int m_mode_sel;
133   int m_rw_sel;
134   int m_odd_hd;
135   UINT8 m_pi;
136
137   attotime m_period;
138
139   live_info cur_live, checkpoint_live;
140   fdc_pll_t cur_pll, checkpoint_pll;
141   emu_timer *t_gen;
142
143   floppy_image_device* get_floppy();
144
145   void live_start();
146   void checkpoint();
147   void rollback();
148   void pll_reset(const attotime &when, const attotime clock);
149   void pll_start_writing(const attotime &tm);
150   void pll_commit(floppy_image_device *floppy, const attotime &tm);
151   void pll_stop_writing(floppy_image_device *floppy, const attotime &tm);
152   int pll_get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit);
153   bool pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit);
154   void pll_save_checkpoint();
155   void pll_retrieve_checkpoint();
156   void live_delay(int state);
157   void live_sync();
158   void live_abort();
159   void live_run(const attotime &limit = attotime::never);
160};
161
162
163// device type definition
164extern const device_type C8050_FDC;
165
166
167
168#endif


Previous 199869 Revisions Next


© 1997-2024 The MAME Team