static int CmdSenseInterStatus(int val, int sens, int tps) { if (sens == SENS_WR && (Status & STATUS_DIO) == 0) { Status |= STATUS_DIO; // Phase result } if (sens == SENS_RD && (Status & STATUS_DIO) != 0) { switch (PosStack++) { case 0: if (Break != 0) { ST0 &= ~ST0_IC1; ST0 |= ST0_IC2; Break = 0; } return(ST0); case 1: FctExec = null; // Prêt pour une nouvelle commande Status &= ~STATUS_DIO & ~STATUS_CB; // Repositionné en Z80->UPD if ((ST0 & (ST0_SE | ST0_IC1)) != 0) { ST0 = ST0_IC2; } EndExePhase(); return(CurrTrack[UnitSel]); } } return(0xFF); }
static public void Write(int port, int val) { port &= 0x101; if (port == 0x101) // Write Data Register { if ((Status & STATUS_DIO) == 0) { if (FctExec == null) { FctExec = TabCmdUPD[val & 0x1F]; Status |= STATUS_CB; PosStack = 0; } FctExec(val, SENS_WR, 0); } } else if (port <= 1) { if (Moteur == 0) { TpsReady = TPS_MOTOR_ON; } Moteur = (byte)(val & 1); if (Moteur == 0) { ST3 &= ~ST3_RY; Break = 1; } } }
static int CmdInvalid(int val, int sens, int tps) { if (sens == SENS_WR && (Status & STATUS_DIO) == 0) { Status |= STATUS_DIO; // phase result } if (sens == SENS_RD && (Status & STATUS_DIO) != 0) { FctExec = null; // Prêt pour une nouvelle commande Status &= ~STATUS_DIO & ~STATUS_CB; // Repositionné en Z80->UPD (phase cmd) EndExePhase(); ST0 = ST0_IC2; // ### ST0 forcé à 0x80 return(ST0); } //Log( MODULENAME, "Commande Invalide appelée.", LOG_INFO ); return(0xFF); }
static public void Reset() { Status = STATUS_RQM; PosStack = 0; FctExec = null; Moteur = 0; IndexSecteur = PosData = 0; ST0 = ST1 = ST2 = ST3 = 0; SRT = 12000; Break = 0; HeadSel = 0; NbSteps = 0; for (UnitSel = 4; --UnitSel > 0;) { NewCylinder = CurrTrack[UnitSel]; MoveTrack(1, 0); } }
static int CmdReadID(int val, int sens, int tps) { if (sens == SENS_WR && (Status & STATUS_DIO) == 0) { if (PosStack++ > 0) { UnitSel = val & 3; HeadSel = (val >> 2) & 1; Status |= STATUS_DIO; } } if (sens == SENS_RD && (Status & STATUS_DIO) != 0) { // TpsNextByte += 16000; switch (PosStack++) { case 2: return(CalcST0()); case 3: return(ST1); case 4: return(ST2); case 5: NextSecteur(ref sectC, ref sectH, ref sectR, ref sectN); return(sectC); case 6: return(sectH); case 7: return(sectR); case 8: FctExec = null; // Prêt pour une nouvelle commande Status &= ~STATUS_CB & ~STATUS_DIO; EndExePhase(); return(sectN); } } return(0xFF); }
static int CmdSpecify(int val, int sens, int tps) { if (sens == SENS_WR && (Status & STATUS_DIO) == 0) { switch (PosStack++) { case 1: SRT = (16 - (val >> 4)) * 2000; // Temps déplacement d'un pas de la tête en µs HUT = val & 0x0F; break; case 2: HLT = val & 0xFE; FctExec = null; Status &= ~STATUS_DIO & ~STATUS_CB; // Repositionné en Z80->UPD (phase cmd) EndExePhase(); break; } } return(0xFF); }
static int CmdSenseDriveStatus(int val, int sens, int tps) { if (sens == SENS_WR && (Status & STATUS_DIO) == 0) { if (PosStack++ > 0) { UnitSel = val & 3; HeadSel = (val >> 2) & 1; ST3 &= 0xF8; ST3 |= UnitSel | (HeadSel << 2); Status |= STATUS_DIO; // Phase result } } if (sens == SENS_RD && (Status & STATUS_DIO) != 0) { FctExec = null; // Prêt pour une nouvelle commande Status &= ~STATUS_DIO & ~STATUS_CB; // Repositionné en Z80->UPD EndExePhase(); return(ST3); } return(0xFF); }
static int WriteDataWithCM(int val, int sens, int tps, int mask) { int tmpC = 0, tmpH = 0, tmpR = 0, tmpN = 0; if (sens == SENS_WR && (Status & STATUS_DIO) == 0) { switch (PosStack++) { case 1: UnitSel = val & 3; HeadSel = (val >> 2) & 1; ST0 &= ~ST0_IC1 & ~ST0_IC2; break; case 2: sectC = val; break; case 3: sectH = val; break; case 4: sectR = val; break; case 5: sectN = val; break; case 6: sectEOT = val; break; case 7: sectGAP = val; break; case 8: sectSize = val; RechercheSecteur(sectC, sectH, sectR, sectN, sectEOT); cntdata = PosData; if ((ST1 & ST1_ND) == 0) { StartExePhase(); if (sectN == 0) { TailleSect = sectSize; } } else { Status |= STATUS_DIO; PosStack++; } break; case 9: Dsk[UnitSel].Data[CurrTrack[UnitSel]][HeadSel][cntdata++] = (byte)val; Dsk[UnitSel].FlagWrite = 1; if ((Status & STATUS_EXE) != 0) { if (--TailleSect > 0) // Tant que fin de secteur pas atteinte { PosStack--; } else { NextSecteur(ref tmpC, ref tmpH, ref tmpR, ref tmpN); if (sectR++ < sectEOT) // Encore des secteurs à transférer ? { RechercheSecteur(sectC, sectH, sectR, sectN, sectEOT); cntdata = PosData; PosStack--; } else { Status |= STATUS_DIO; EndExePhase(); // Dernier octet à envoyer avant résultat } } } break; } } if (sens == SENS_RD && (Status & STATUS_DIO) != 0) { switch (PosStack++) { case 10: ST0 &= ~ST0_SE; ST0 |= ST0_IC1; // ### à voir CptOverRun = 0; return(ST0); case 11: return(ST1); case 12: return(ST2); case 13: return(sectC); case 14: return(sectH); case 15: return(sectR); case 16: FctExec = null; // Prêt pour une nouvelle commande Status &= ~STATUS_DIO & ~STATUS_CB; // Repositionné en Z80->UPD EndExePhase(); return(sectN); } } return(0xFF); }
static int ReadDataWithCM(int val, int sens, int tps, int mask) { int ret, tmpC = 0, tmpH = 0, tmpR = 0, tmpN = 0; if (sens == SENS_WR && (Status & STATUS_DIO) == 0) { switch (PosStack++) { case 1: UnitSel = val & 3; HeadSel = (val >> 2) & 1; ST0 &= ~ST0_IC1 & ~ST0_IC2; break; case 2: sectC = val; break; case 3: sectH = val; break; case 4: sectR = val; break; case 5: sectN = val; break; case 6: sectEOT = val; break; case 7: sectGAP = val; break; case 8: sectSize = val; RechercheSecteur(sectC, sectH, sectR, sectN, sectEOT); ST2 ^= mask; cntdata = PosData; Status |= STATUS_DIO; if ((ST1 & ST1_ND) == 0) { StartExePhase(); TpsOverRun = TPS_OVER_RUN * 2000; //### Valeur arbitraire, temps entre id et données secteurs CptOverRun = 1; if (sectN == 0) { TailleSect = sectSize; } } else { PosStack++; Break = 1; // Ne peut pas passer en EXECUTE } break; } } if (sens == SENS_RD && (Status & STATUS_DIO) != 0) { switch (PosStack++) { case 9: TpsOverRun = TPS_OVER_RUN; ret = Dsk[UnitSel].Data[CurrTrack[UnitSel]][HeadSel][cntdata++]; if ((Status & STATUS_EXE) != 0) { if (--TailleSect > 0) // Tant que fin de secteur pas atteinte { PosStack--; } else { NextSecteur(ref tmpC, ref tmpH, ref tmpR, ref tmpN); if (sectR < sectEOT) // Encore des secteurs à transférer ? { RechercheSecteur(sectC, sectH, ++sectR, sectN, sectEOT); cntdata = PosData; PosStack--; } else { CptOverRun = 0; EndExePhase(); // Dernier octet à envoyer avant résultat } } } return(ret); case 10: ST0 &= ~ST0_SE; ST0 |= ST0_IC1; // ### à voir CptOverRun = 0; return(ST0); case 11: return(ST1); case 12: return(ST2); case 13: return(sectC); case 14: return(sectH); case 15: return(sectR); case 16: FctExec = null; // Prêt pour une nouvelle commande Status &= ~STATUS_DIO & ~STATUS_CB; // Repositionné en Z80->UPD return(sectN); } } return(0xFF); }
static int CmdReadTrack(int val, int sens, int tps) { int ret; if (sens == SENS_WR && (Status & STATUS_DIO) == 0) { switch (PosStack++) { case 1: UnitSel = val & 3; HeadSel = (val >> 2) & 1; ST0 &= ~ST0_IC1 & ~ST0_IC2; break; case 2: sectC = val; break; case 3: sectH = val; break; case 4: sectR = val; break; case 5: sectN = val; break; case 6: sectEOT = val; break; case 7: sectGAP = val; break; case 8: sectSize = val; SetSecteur(posSect); // Se positionne sur le premier secteur après le trou d'index" cntdata = PosData; Status |= STATUS_DIO; if ((ST1 & ST1_ND) == 0) { StartExePhase(); TpsOverRun = TPS_OVER_RUN * 8000; //### Valeur arbitraire, temps entre id et données secteurs CptOverRun = 1; if (sectN == 0) { TailleSect = sectSize; } } else { PosStack++; Break = 1; // Ne peut pas passer en EXECUTE } break; } } if (sens == SENS_RD && (Status & STATUS_DIO) != 0) { switch (PosStack++) { case 9: TpsOverRun = TPS_OVER_RUN; //* 6250; // ##### GRRR posExtra = -1; ret = Dsk[UnitSel].Data[CurrTrack[UnitSel]][HeadSel][cntdata++]; if ((Status & STATUS_EXE) != 0) { if (--TailleSect > 0) // Tant que fin de secteur pas atteinte { PosStack--; } } else { PosStack++; } return(ret); case 10: TpsOverRun = TPS_OVER_RUN * 6250; ret = GetExtraData(ref posExtra, CurrTrackDatasDSK[UnitSel][HeadSel].Gap3); if ((Status & STATUS_EXE) != 0) { if (posExtra > 0) { PosStack--; } else { if (posSect++ < CurrTrackDatasDSK[UnitSel][HeadSel].NbSect) // Encore des secteurs à transférer ? { SetSecteur(posSect); cntdata = PosData; PosStack -= 2; } else { CptOverRun = 0; EndExePhase(); // Dernier octet à envoyer avant résultat } } } return(ret); case 11: ST0 &= ~ST0_SE; ST0 |= ST0_IC1; // ### à voir CptOverRun = 0; return(ST0); case 12: return(ST1); case 13: return(ST2); case 14: return(sectC); case 15: return(sectH); case 16: return(sectR); case 17: FctExec = null; // Prêt pour une nouvelle commande Status &= ~STATUS_DIO & ~STATUS_CB; // Repositionné en Z80->UPD return(sectN); } } return(0xFF); }
static void MoveTrack(int tps, int maxMove) { if (tps == 0) { TimeMoveTrack = 0; NbSteps = maxMove; ST0 &= ~ST0_SE & ~ST0_EC; ST3 &= ~ST3_RY; Status &= ~STATUS_RQM; // UPD Occupé à déplacer la tête StartExePhase(); TpsNextByte += SRT; } else if (CurrTrack[UnitSel] == NewCylinder || NbSteps == 0) { FctExec = null; ST0 &= ~ST0_IC1 & ~ST0_IC2; ST0 |= ST0_SE; if (UnitSel < 2 && Dsk[UnitSel].ImageOk) { CurrTrackDatasDSK[UnitSel][0] = Dsk[UnitSel].Tracks[CurrTrack[UnitSel]][0]; CurrTrackDatasDSK[UnitSel][1] = Dsk[UnitSel].Tracks[CurrTrack[UnitSel]][1]; ST3 |= ST3_RY; } if (CurrTrack[UnitSel] == 0) { ST3 |= ST3_T0; } else { ST3 &= ~ST3_T0; } TpsNextByte = 0; IndexSecteur = PosData = 0; if (CurrTrack[UnitSel] != NewCylinder) { ST0 |= ST0_EC; } Status &= ~STATUS_CB & ~STATUS_DIO; // ## pourquoi mettre le ~STATUS_CB en commentaire ??? Status |= STATUS_RQM; EndExePhase(); } else { TpsNextByte += tps; TimeMoveTrack += tps; if (TimeMoveTrack > SRT) { TimeMoveTrack -= SRT; if (CurrTrack[UnitSel] > NewCylinder) { CurrTrack[UnitSel]--; } else { CurrTrack[UnitSel]++; } NbSteps--; } } }