Previous 199869 Revisions Next

r19282 Monday 3rd December, 2012 at 19:12:34 UTC by O. Galibert
upd765: Try another hypothesis [O. Galibert]
[src/emu/machine]upd765.c upd765.h

trunk/src/emu/machine/upd765.c
r19281r19282
150150      flopi[i].sub_state = IDLE;
151151      flopi[i].live = false;
152152      flopi[i].ready = !ready_polled;
153      flopi[i].irq = floppy_info::IRQ_NONE;
153      flopi[i].st0 = i;
154      flopi[i].st0_filled = false;
154155   }
155156   data_irq = false;
156   polled_irq = false;
157   other_irq = false;
157158   internal_drq = false;
158159   fifo_pos = 0;
159160   command_pos = 0;
r19281r19282
167168   cur_live.next_state = -1;
168169   cur_live.fi = NULL;
169170   tc_done = false;
170   st0 = st1 = st2 = st3 = 0x00;
171   st1 = st2 = st3 = 0x00;
171172
172173   check_irq();
173174   if(ready_polled)
r19281r19282
11961197   }
11971198
11981199   case C_SENSE_INTERRUPT_STATUS: {
1200      // Documentation is somewhat contradictory w.r.t polling
1201      // and irq.  PC bios, especially 5150, requires that only
1202      // one irq happens.  That's also wait the ns82077a doc
1203      // says it does.  OTOH, a number of docs says you need to
1204      // call SIS 4 times, once per drive...
1205      //
1206      // There's also the interaction with the seek irq.  The
1207      // somewhat borderline tf20 code seems to think that
1208      // essentially ignoring the polling irq should work.
1209      //
1210      // And the pc98 expects to be able to accumulate irq reasons
1211      // for different drives and things to work.
1212      //
1213      // Current hypothesis:
1214      // - each drive has its own st0 and irq trigger
1215      // - SIS drops the irq always, but also returns the first full st0 it finds
1216
11991217      main_phase = PHASE_RESULT;
12001218
12011219      int fid;
1202      for(fid=0; fid<4 && flopi[fid].irq == floppy_info::IRQ_NONE; fid++);
1220      for(fid=0; fid<4 && !flopi[fid].st0_filled; fid++);
12031221      if(fid == 4) {
1204         st0 = ST0_UNK;
1205         result[0] = st0;
1222         result[0] = ST0_UNK;
12061223         result_pos = 1;
12071224         logerror("%s: command sense interrupt status (%02x)\n", tag(), result[0]);
12081225         break;
12091226      }
1227
12101228      floppy_info &fi = flopi[fid];
1211      if(fi.irq == floppy_info::IRQ_POLLED) {
1212         // Documentation is somewhat contradictory w.r.t polling
1213         // and irq.  PC bios, especially 5150, requires that only
1214         // one irq happens.  That's also wait the ns82077a doc
1215         // says it does.  OTOH, a number of docs says you need to
1216         // call SIS 4 times, once per drive...
1217         //
1218         // There's also the interaction with the seek irq.  The
1219         // somewhat borderline tf20 code seems to think that
1220         // essentially ignoring the polling irq should work.
1221         //
1222         // So at that point the best bet seems to drop the
1223         // "polled" irq as soon as a SIS happens, and override any
1224         // polled-in-waiting information when a seek irq happens
1225         // for a given floppy.
1229      fi.st0_filled = false;
12261230
1227         st0 = ST0_ABRT | fid;
1228      }
1229      fi.irq = floppy_info::IRQ_NONE;
1231      result[0] = fi.st0;
1232      result[1] = fi.pcn;
12301233
1231      polled_irq = false;
1232
1233      result[0] = st0;
1234      result[1] = fi.pcn;
12351234      logerror("%s: command sense interrupt status (fid=%d %02x %02x)\n", tag(), fid, result[0], result[1]);
12361235      result_pos = 2;
12371236
1237      other_irq = false;
12381238      check_irq();
12391239      break;
12401240   }
r19281r19282
12671267   if(data_completion)
12681268      data_irq = true;
12691269   else
1270      fi.irq = floppy_info::IRQ_SEEK;
1270      other_irq = true;
1271   fi.st0_filled = true;
12711272   check_irq();
12721273}
12731274
r19281r19282
13371338            if(done)
13381339               fi.pcn = 0;
13391340            else if(!fi.counter) {
1340               st0 = ST0_FAIL|ST0_SE|ST0_EC;
1341               fi.st0 = ST0_FAIL|ST0_SE|ST0_EC | fi.id;
13411342               command_end(fi, false);
13421343               return;
13431344            }
r19281r19282
13471348            break;
13481349         }
13491350         if(done) {
1350            st0 = ST0_SE;
1351            fi.st0 = ST0_SE | fi.id;
13511352            command_end(fi, false);
13521353            return;
13531354         }
r19281r19282
13821383          command[8],
13831384          cur_rate);
13841385
1385   st0 = command[1] & 7;
1386   fi.st0 = command[1] & 7;
13861387   st1 = ST1_MA;
13871388   st2 = 0x00;
13881389
r19281r19282
14001401            fi.sub_state = SEEK_DONE;
14011402            break;
14021403         }
1403         st0 |= ST0_SE;
1404         fi.st0 |= ST0_SE;
14041405         if(fi.dev) {
14051406            fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0);
14061407            fi.dev->stp_w(0);
r19281r19282
14391440
14401441      case SCAN_ID:
14411442         if(cur_live.crc) {
1442            st0 |= ST0_FAIL;
1443            fi.st0 |= ST0_FAIL;
14431444            st1 |= ST1_DE|ST1_ND;
14441445            fi.sub_state = COMMAND_DONE;
14451446            break;
r19281r19282
14511452                  st2 |= ST2_WC|ST2_BC;
14521453               else
14531454                  st2 |= ST2_WC;
1454               st0 |= ST0_FAIL;
1455               fi.st0 |= ST0_FAIL;
14551456               fi.sub_state = COMMAND_DONE;
14561457               break;
14571458            }
r19281r19282
14711472         return;
14721473
14731474      case SCAN_ID_FAILED:
1474         st0 |= ST0_FAIL;
1475         fi.st0 |= ST0_FAIL;
14751476         st1 |= ST1_ND;
14761477         fi.sub_state = COMMAND_DONE;
14771478         break;
14781479
14791480      case SECTOR_READ: {
14801481         if(st2 & ST2_MD) {
1481            st0 |= ST0_FAIL;
1482            fi.st0 |= ST0_FAIL;
14821483            fi.sub_state = COMMAND_DONE;
14831484            break;
14841485         }
14851486         if(cur_live.crc) {
1486            st0 |= ST0_FAIL;
1487            fi.st0 |= ST0_FAIL;
14871488            st1 |= ST1_DE;
14881489            st2 |= ST2_CM;
14891490            fi.sub_state = COMMAND_DONE;
r19281r19282
15071508                  command[2]++;
15081509            }
15091510            if(!tc_done && done) {
1510               st0 |= ST0_FAIL;
1511               fi.st0 |= ST0_FAIL;
15111512               st1 |= ST1_EN;
15121513            }
15131514         }
r19281r19282
15211522
15221523      case COMMAND_DONE:
15231524         main_phase = PHASE_RESULT;
1524         result[0] = st0;
1525         result[0] = fi.st0;
15251526         result[1] = st1;
15261527         result[2] = st2;
15271528         result[3] = command[2];
r19281r19282
15631564   if(fi.dev)
15641565      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
15651566
1566   st0 = command[1] & 7;
1567   fi.st0 = command[1] & 7;
15671568   st1 = ST1_MA;
15681569   st2 = 0x00;
15691570
r19281r19282
15861587            return;
15871588         }
15881589         if(cur_live.crc) {
1589            st0 |= ST0_FAIL;
1590            fi.st0 |= ST0_FAIL;
15901591            st1 |= ST1_DE|ST1_ND;
15911592            fi.sub_state = COMMAND_DONE;
15921593            break;
r19281r19282
15991600         return;
16001601
16011602      case SCAN_ID_FAILED:
1602         st0 |= ST0_FAIL;
1603         fi.st0 |= ST0_FAIL;
16031604         st1 |= ST1_ND;
16041605         fi.sub_state = COMMAND_DONE;
16051606         break;
r19281r19282
16231624                  command[2]++;
16241625            }
16251626            if(!tc_done && done) {
1626               st0 |= ST0_FAIL;
1627               fi.st0 |= ST0_FAIL;
16271628               st1 |= ST1_EN;
16281629            }
16291630         }
r19281r19282
16371638
16381639      case COMMAND_DONE:
16391640         main_phase = PHASE_RESULT;
1640         result[0] = st0;
1641         result[0] = fi.st0;
16411642         result[1] = st1;
16421643         result[2] = st2;
16431644         result[3] = command[2];
r19281r19282
18461847   if(fi.dev)
18471848      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
18481849
1849   st0 = command[1] & 7;
1850   fi.st0 = command[1] & 7;
18501851   st1 = 0x00;
18511852   st2 = 0x00;
18521853
r19281r19282
18681869
18691870      case SCAN_ID:
18701871         if(cur_live.crc) {
1871            st0 |= ST0_FAIL;
1872            fi.st0 |= ST0_FAIL;
18721873            st1 |= ST1_MA|ST1_DE|ST1_ND;
18731874         }
18741875         fi.sub_state = COMMAND_DONE;
18751876         break;
18761877
18771878      case SCAN_ID_FAILED:
1878         st0 |= ST0_FAIL;
1879         fi.st0 |= ST0_FAIL;
18791880         st1 |= ST1_ND|ST1_MA;
18801881         fi.sub_state = COMMAND_DONE;
18811882         break;
18821883
18831884      case COMMAND_DONE:
18841885         main_phase = PHASE_RESULT;
1885         result[0] = st0;
1886         result[0] = fi.st0;
18861887         result[1] = st1;
18871888         result[2] = st2;
18881889         result[3] = cur_live.idbuf[0];
r19281r19282
19031904void upd765_family_device::check_irq()
19041905{
19051906   bool old_irq = cur_irq;
1906   cur_irq = data_irq || polled_irq || internal_drq;
1907   for(int i=0; i<4; i++)
1908      cur_irq = cur_irq || flopi[i].irq == floppy_info::IRQ_SEEK;
1907   cur_irq = data_irq || other_irq || internal_drq;
19091908   cur_irq = cur_irq && (dor & 4) && (dor & 8);
19101909   if(cur_irq != old_irq && !intrq_cb.isnull()) {
19111910      logerror("%s: irq = %d\n", tag(), cur_irq);
r19281r19282
19691968      if(ready != flopi[fid].ready) {
19701969         logerror("%s: polled %d : %d -> %d\n", tag(), fid, flopi[fid].ready, ready);
19711970         flopi[fid].ready = ready;
1972         if(flopi[fid].irq == floppy_info::IRQ_NONE) {
1973            flopi[fid].irq = floppy_info::IRQ_POLLED;
1974            polled_irq = true;
1971         if(!flopi[fid].st0_filled) {
1972            flopi[fid].st0 = ST0_ABRT | fid;
1973            flopi[fid].st0_filled = true;
1974            other_irq = true;
19751975            changed = true;
19761976         }
19771977      }
19781978   }
1979   if(changed)
1980      check_irq();
1979
1980   check_irq();
19811981}
19821982
19831983void upd765_family_device::index_callback(floppy_image_device *floppy, int state)
trunk/src/emu/machine/upd765.h
r19281r19282
250250   };
251251
252252   struct floppy_info {
253      enum { IRQ_NONE, IRQ_SEEK, IRQ_POLLED };
253      enum { IRQ_NONE, IRQ_POLLED, IRQ_SEEK, IRQ_DONE };
254254      emu_timer *tm;
255255      floppy_image_device *dev;
256256      int id;
257257      int main_state, sub_state;
258258      int dir, counter;
259      UINT8 pcn;
260      int irq;
259      UINT8 pcn, st0;
260      bool st0_filled;
261261      bool live, index, ready;
262262   };
263263
r19281r19282
287287
288288   live_info cur_live, checkpoint_live;
289289   line_cb intrq_cb, drq_cb;
290   bool cur_irq, polled_irq, data_irq, drq, internal_drq, tc, tc_done, locked, mfm;
290   bool cur_irq, other_irq, data_irq, drq, internal_drq, tc, tc_done, locked, mfm;
291291   floppy_info flopi[4];
292292
293293   int fifo_pos, fifo_expected, command_pos, result_pos;
294294   bool fifo_write;
295295   UINT8 dor, dsr, msr, fifo[16], command[16], result[16];
296   UINT8 st0, st1, st2, st3;
296   UINT8 st1, st2, st3;
297297   UINT8 fifocfg, dor_reset;
298298   UINT8 precomp, perpmode;
299299   UINT16 spec;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team