Beispiel #1
0
        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);
        }
Beispiel #2
0
        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;
                }
            }
        }
Beispiel #3
0
 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);
 }
Beispiel #4
0
 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);
     }
 }
Beispiel #5
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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
 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);
 }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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--;
                }
            }
        }