Previous 199869 Revisions Next

r41809 Friday 20th November, 2015 at 21:52:48 UTC by Olivier Galibert
wozfdc: Warp factor 4 Scotty [O. Galibert]
[src/devices/machine]wozfdc.cpp wozfdc.h

trunk/src/devices/machine/wozfdc.cpp
r250320r250321
7676   save_item(NAME(active));
7777   save_item(NAME(phases));
7878   save_item(NAME(external_io_select));
79   save_item(NAME(cur_lss.tm));
80   save_item(NAME(cur_lss.cycles));
81   save_item(NAME(cur_lss.data_reg));
82   save_item(NAME(cur_lss.address));
83   save_item(NAME(cur_lss.write_start_time));
84//  save_item(NAME(cur_lss.write_buffer));
85   save_item(NAME(cur_lss.write_position));
86   save_item(NAME(cur_lss.write_line_active));
87   save_item(NAME(predicted_lss.tm));
88   save_item(NAME(predicted_lss.cycles));
89   save_item(NAME(predicted_lss.data_reg));
90   save_item(NAME(predicted_lss.address));
91   save_item(NAME(predicted_lss.write_start_time));
92//  save_item(NAME(predicted_lss.write_buffer));
93   save_item(NAME(predicted_lss.write_position));
94   save_item(NAME(predicted_lss.write_line_active));
79   save_item(NAME(cycles));
80   save_item(NAME(data_reg));
81   save_item(NAME(address));
82   save_item(NAME(write_start_time));
83   save_item(NAME(write_position));
84   save_item(NAME(write_line_active));
9585   save_item(NAME(drvsel));
9686   save_item(NAME(enable1));
9787}
r250320r250321
10494   mode_write = false;
10595   mode_load = false;
10696   last_6502_write = 0x00;
107   cur_lss.tm = machine().time();
108   cur_lss.cycles = time_to_cycles(cur_lss.tm);
109   cur_lss.data_reg = 0x00;
110   cur_lss.address = 0x00;
111   cur_lss.write_start_time = attotime::never;
112   cur_lss.write_position = 0;
113   cur_lss.write_line_active = false;
114   predicted_lss.tm = attotime::never;
97   cycles = time_to_cycles(machine().time());
98   data_reg = 0x00;
99   address = 0x00;
100   write_start_time = attotime::never;
101   write_position = 0;
102   write_line_active = false;
115103   external_io_select = false;
104
105   // Just a timer to be sure that the lss is updated from time to
106   // time, so that there's no hiccup when it's talked to again.
107   timer->adjust(attotime::from_msec(10), 0, attotime::from_msec(10));
116108}
117109
118110void wozfdc_device::a3_update_drive_sel()
r250320r250321
152144         floppy->mon_w(true);
153145      }
154146      floppy = newflop;
155      if(active) {
147      if(active)
156148         floppy->mon_w(false);
157         lss_predict();
158      }
159149   }
160150}
161151
r250320r250321
188178         floppy->mon_w(true);
189179      active = MODE_IDLE;
190180   }
191
192   if(active)
193      lss_predict();
194181}
195182
196183/*-------------------------------------------------
r250320r250321
201188{
202189   control(offset);
203190
204   if(!(offset & 1))
205      return cur_lss.data_reg;
191   if(!(offset & 1)) {
192      lss_sync();
193      return data_reg;
194   }
206195   return 0xff;
207196}
208197
r250320r250321
214203WRITE8_MEMBER(wozfdc_device::write)
215204{
216205   control(offset);
206   lss_sync();
217207   last_6502_write = data;
218   lss_predict();
219208}
220209
221210void wozfdc_device::phase(int ph, bool on)
r250320r250321
235224      if(active)
236225         lss_sync();
237226      phase(offset >> 1, offset & 1);
238      if(active)
239         lss_predict();
240227
241228   } else
242229      switch(offset) {
r250320r250321
262249            break;
263250         }
264251         break;
265         case 0xa:
252      case 0xa:
266253            external_io_select = false;
267254            if(floppy != floppy0->get_device()) {
268255               if(active) {
r250320r250321
270257                  floppy->mon_w(true);
271258               }
272259            floppy = floppy0->get_device();
273            if(active) {
260            if(active)
274261               floppy->mon_w(false);
275               lss_predict();
276            }
277262         }
278263         break;
279264      case 0xb:
r250320r250321
287272                  floppy->mon_w(true);
288273               }
289274               floppy = floppy1->get_device();
290               if(active) {
275               if(active)
291276                  floppy->mon_w(false);
292                  lss_predict();
293               }
294277            }
295278         }
296279         else
r250320r250321
302285         if(mode_load) {
303286            if(active) {
304287               lss_sync();
305               cur_lss.address &= ~0x04;
288               address &= ~0x04;
306289            }
307290            mode_load = false;
308            if(active)
309               lss_predict();
310291         }
311292         break;
312293      case 0xd:
313294         if(!mode_load) {
314295            if(active) {
315296               lss_sync();
316               cur_lss.address |= 0x04;
297               address |= 0x04;
317298            }
318299            mode_load = true;
319            if(active)
320               lss_predict();
321300         }
322301         break;
323302      case 0xe:
324303         if(mode_write) {
325304            if(active) {
326305               lss_sync();
327               cur_lss.address &= ~0x08;
306               address &= ~0x08;
328307            }
329308            mode_write = false;
330            if(active)
331               lss_predict();
332309         }
333310         break;
334311      case 0xf:
335312         if(!mode_write) {
336313            if(active) {
337314               lss_sync();
338               cur_lss.address |= 0x08;
339               cur_lss.write_start_time = machine().time();
315               address |= 0x08;
316               write_start_time = machine().time();
340317               if(floppy)
341                  floppy->set_write_splice(cur_lss.write_start_time);
318                  floppy->set_write_splice(write_start_time);
342319            }
343320            mode_write = true;
344            if(active)
345               lss_predict();
346321         }
347322         break;
348323      }
r250320r250321
365340
366341void wozfdc_device::lss_start()
367342{
368   cur_lss.tm = machine().time();
369   cur_lss.cycles = time_to_cycles(cur_lss.tm);
370   cur_lss.data_reg = 0x00;
371   cur_lss.address &= ~0x0e;
372   cur_lss.write_position = 0;
373   cur_lss.write_start_time = mode_write ? machine().time() : attotime::never;
374   cur_lss.write_line_active = false;
343   cycles = time_to_cycles(machine().time());
344   data_reg = 0x00;
345   address &= ~0x0e;
346   write_position = 0;
347   write_start_time = mode_write ? machine().time() : attotime::never;
348   write_line_active = false;
375349   if(mode_write && floppy)
376      floppy->set_write_splice(cur_lss.write_start_time);
377   lss_predict();
350      floppy->set_write_splice(write_start_time);
378351}
379352
380void wozfdc_device::lss_delay(UINT64 cycles, const attotime &tm, UINT8 data_reg, UINT8 address, bool write_line_active)
381{
382   if(data_reg & 0x80)
383      address |= 0x02;
384   else
385      address &= ~0x02;
386   predicted_lss.cycles = cycles;
387   predicted_lss.tm = tm;
388   predicted_lss.data_reg = data_reg;
389   predicted_lss.address = address;
390   predicted_lss.write_line_active = write_line_active;
391   attotime mtm = machine().time();
392   if(predicted_lss.tm > mtm)
393      timer->adjust(predicted_lss.tm - mtm);
394}
395
396void wozfdc_device::lss_delay(UINT64 cycles, UINT8 data_reg, UINT8 address, bool write_line_active)
397{
398   lss_delay(cycles, cycles_to_time(cycles), data_reg, address, write_line_active);
399}
400
401void wozfdc_device::commit_predicted()
402{
403   cur_lss = predicted_lss;
404   assert(!mode_write || (cur_lss.write_line_active && (cur_lss.address & 0x80)) || ((!cur_lss.write_line_active) && !(cur_lss.address & 0x80)));
405   if(mode_write) {
406      if(floppy)
407         floppy->write_flux(cur_lss.write_start_time, cur_lss.tm, cur_lss.write_position, cur_lss.write_buffer);
408      cur_lss.write_start_time = cur_lss.tm;
409      cur_lss.write_position = 0;
410   }
411
412   predicted_lss.tm = attotime::never;
413}
414
415353void wozfdc_device::lss_sync()
416354{
417   attotime tm = machine().time();
418   if(!predicted_lss.tm.is_never() && predicted_lss.tm <= tm)
419      commit_predicted();
355   if(!active)
356      return;
420357
421   while(cur_lss.tm < tm) {
422      lss_predict(tm);
423      commit_predicted();
424   }
425}
358   attotime next_flux = floppy ? floppy->get_next_transition(cycles_to_time(cycles) - attotime::from_usec(1)) : attotime::never;
426359
427void wozfdc_device::lss_predict(attotime limit)
428{
429   predicted_lss.write_start_time = cur_lss.write_start_time;
430   predicted_lss.write_position = cur_lss.write_position;
431   memcpy(predicted_lss.write_buffer, cur_lss.write_buffer, cur_lss.write_position * sizeof(attotime));
432   bool write_line_active = cur_lss.write_line_active;
433
434   attotime next_flux = floppy ? floppy->get_next_transition(cur_lss.tm - attotime::from_usec(1)) : attotime::never;
435
436   if(limit == attotime::never)
437      limit = machine().time() + attotime::from_usec(50);
438
439   UINT64 cycles = cur_lss.cycles;
440   UINT64 cycles_limit = time_to_cycles(limit);
360   UINT64 cycles_limit = time_to_cycles(machine().time());
441361   UINT64 cycles_next_flux = next_flux != attotime::never ? time_to_cycles(next_flux) : UINT64(-1);
442362   UINT64 cycles_next_flux_down = cycles_next_flux != UINT64(-1) ? cycles_next_flux+1 : UINT64(-1);
443363
444   UINT8 address = cur_lss.address;
445   UINT8 data_reg = cur_lss.data_reg;
446
447364   if(cycles >= cycles_next_flux && cycles < cycles_next_flux_down)
448365      address &= ~0x10;
449366   else
r250320r250321
463380            if((write_line_active && !(address & 0x80)) ||
464381               (!write_line_active && (address & 0x80))) {
465382               write_line_active = !write_line_active;
466               assert(predicted_lss.write_position != 32);
467               predicted_lss.write_buffer[predicted_lss.write_position++] = cycles_to_time(cycles);
383               assert(write_position != 32);
384               write_buffer[write_position++] = cycles_to_time(cycles);
468385            }
469386         }
470387
471388         address = (address & 0x1e) | (opcode & 0xc0) | ((opcode & 0x20) >> 5) | ((opcode & 0x10) << 1);
472389         switch(opcode & 0x0f) {
473390         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
474            if(data_reg) {
475               lss_delay(cycles+1, 0x00, address, write_line_active);
476               return;
477            }
391            data_reg = 0x00;
478392            break;
479393         case 0x8: case 0xc:
480394            break;
481395         case 0x9:
482            lss_delay(cycles+1, data_reg << 1, address, write_line_active);
483            return;
396            data_reg <<= 1;
397            break;
484398         case 0xa: case 0xe:
485            lss_delay(cycles+1, (data_reg >> 1) | (floppy && floppy->wpt_r() ? 0x80 : 0x00), address, write_line_active);
486            return;
399            data_reg = (data_reg >> 1) | (floppy && floppy->wpt_r() ? 0x80 : 0x00);
400            break;
487401         case 0xb: case 0xf:
488            lss_delay(cycles+1, last_6502_write, address, write_line_active);
489            return;
402            data_reg = last_6502_write;
403            break;
490404         case 0xd:
491            lss_delay(cycles+1, (data_reg << 1) | 0x01, address, write_line_active);
492            return;
405            data_reg = (data_reg << 1) | 0x01;
406            break;
493407         }
408         if(data_reg & 0x80)
409            address |= 0x02;
410         else
411            address &= ~0x02;
494412         cycles++;
495413      }
496414
r250320r250321
503421         cycles_next_flux_down = cycles_next_flux != UINT64(-1) ? cycles_next_flux+1 : UINT64(-1);
504422      }
505423   }
506
507   lss_delay(cycles, limit, data_reg, address, write_line_active);
508424}
509425
510426// set the two images for the Disk II
trunk/src/devices/machine/wozfdc.h
r250320r250321
5151      MODE_IDLE, MODE_ACTIVE, MODE_DELAY
5252   };
5353
54   struct lss {
55      attotime tm;
56      UINT64 cycles;
57      UINT8 data_reg, address;
58      attotime write_start_time;
59      attotime write_buffer[32];
60      int write_position;
61      bool write_line_active;
62   };
54   UINT64 cycles;
55   UINT8 data_reg, address;
56   attotime write_start_time;
57   attotime write_buffer[32];
58   int write_position;
59   bool write_line_active;
6360
6461   const UINT8 *m_rom_p6;
6562   UINT8 last_6502_write;
r250320r250321
7067   bool external_drive_select;
7168   bool external_io_select;
7269
73   lss cur_lss, predicted_lss;
74
7570   int drvsel;
7671   int enable1;
7772
r250320r250321
8277   void a3_update_drive_sel();
8378
8479   void lss_start();
85   void lss_delay(UINT64 cycles, const attotime &tm, UINT8 data_reg, UINT8 address, bool write_line_active);
86   void lss_delay(UINT64 cycles, UINT8 data_reg, UINT8 address, bool write_line_active);
8780   void lss_sync();
88   void lss_predict(attotime limit = attotime::never);
89   void commit_predicted();
9081};
9182
9283class diskii_fdc : public wozfdc_device


Previous 199869 Revisions Next


© 1997-2024 The MAME Team