Сообщение от
Alex_K
Исходников нет, да и отладчика тоже, сказать сложно.
Дисковод писал очень давно, и совсем про него не помню. Хочешь, сам посмотри.
Код:
static struct { // Определить структуру, описывающую дисководы
UINT8 Track, // Номер трека (00..79, при over-позицировании > 79)
Side, // Сторона (0 - нижняя головка, 1 - верхняя головка)
Motor, // Мотор (00 - выключен, иначе включен)
PrevMotor, // Предыдущее состояние мотора (для иконок дискет)
Mode, // Режим (00 - нет чтения/записи, 01 - чтение, 02 - запись)
Ready; // Готовность данных (00 - нет данных, иначе есть данные)
UINT8 PosType, // Текущее положение на треке (00 - межсекторное пространство, иначе сектор)
Sector; // Текущий сектор (0..9)
UINT32 CurrPos; // Текущая позиция в словах внутри сектора (0..511) либо внутри межсекторного пространства (0..nnnn)
UINT8 *ImagePTR; // Указатель на образ диска (образ 819200 байт)
UINT16 ControlSp[50];// Массив для размещения текущей межсекторной служебной информации
} Floppy[4];
UINT16 FASTC PPU_RdW_FDD_STATE(void) { // Регистр состояния Floppy-диска
UINT16 State = 0;
UINT8 Numb = 3 - (PPU_FDD_STATE & 0x3); // Numb - номер дисковода (0..3)
if (Floppy[Numb].Track == 0) // Если трек = 0, то
State |= 0x0001; // устанавливаем бит TR0
State |= 0x0002; // Дисковод готов к работе (всегда)
// State |= 0x0004; // [T] Запись на диск запрещена
if (Floppy[Numb].Ready) // Если есть готовность данных
State |= 0x0080;
else { // Иначе, если нет готовности данных, то синхронизация
if (Floppy[Numb].PosType) { // Если находимся на секторе, то автоматом
// перепозицируемся на следующую за сектором
// первую синхропоследовательность $A1A1
// (синхро заголовка сектора)
Floppy[Numb].CurrPos = 20; // Позицируемся на первую $A1A1
Floppy[Numb].PosType = 0; // межсекторного пространства
if ((Floppy[Numb].Sector +=1) > 9) // Перейти к следующему сектору
Floppy[Numb].Sector = 0; // Если достигли сектора 10, то переход к сектору 0
Floppy[Numb].ControlSp[22] = (Floppy[Numb].Track << 8) | // Прописываем в служебное поле
Floppy[Numb].Side; // номер трека / головки
Floppy[Numb].ControlSp[23] = ((Floppy[Numb].Sector + 1) << 8) | // номер сектора / длина
2; //
}
else { // Если находимся на межсекторном пространстве
if (Floppy[Numb].ControlSp[Floppy[Numb].CurrPos] == 0xA1A1) { // Если достигли синхропоследовательности
Floppy[Numb].Ready = 1; // то устанавливаем готовность данных
State |= 0x0080;
}
else {
if ((Floppy[Numb].CurrPos += 1) > 41) { // Если достигли конца служебной области
Floppy[Numb].CurrPos = 0; // Позицируемся на начало
Floppy[Numb].PosType = 1; // сектора
}
}
}
}
State |= 0x4000; // [T] Контрольная сумма всегда правильная
return(State);
}
UINT16 FASTC PPU_RdW_FDD_DATA(void) { // Регистр данных Floppy-диска
UINT16 Value;
UINT8 Numb = 3 - (PPU_FDD_STATE & 0x3); // Numb - номер дисковода (0..3)
if (Floppy[Numb].PosType) { // Если находимся на секторе (сектор 512 байт)
Value = *(UINT16*)(Floppy[Numb].ImagePTR + // Слово данных
((Floppy[Numb].Track << 1) + Floppy[Numb].Side) * 5120 +
(Floppy[Numb].CurrPos << 1) +
Floppy[Numb].Sector * 512);
Value = (Value >> 8) | ((Value & 0x00FF) << 8); // Обмен байтов в слове
Floppy[Numb].Mode = 1; // Режим 'чтение' (для цветовой индикации)
if ((Floppy[Numb].CurrPos += 1) > 255) { // Если достигли конца сектора
Floppy[Numb].CurrPos = 0; // Позицируемся на начало
Floppy[Numb].PosType = 0; // межсекторного пространства
if ((Floppy[Numb].Sector +=1) > 9) // Перейти к следующему сектору
Floppy[Numb].Sector = 0; // Если достигли сектора 10, то переход к сектору 0
Floppy[Numb].ControlSp[22] = (Floppy[Numb].Track << 8) | // Прописываем в служебное поле
Floppy[Numb].Side; // номер трека / головки
Floppy[Numb].ControlSp[23] = ((Floppy[Numb].Sector + 1) << 8) | // номер сектора / длина
2; //
Floppy[Numb].Mode = 0; // Режим 'бездействие' (для цветовой индикации)
}
}
else { // Иначе находимся на межсекторном пространстве
Value = Floppy[Numb].ControlSp[Floppy[Numb].CurrPos]; // Слово данных
if ((Floppy[Numb].CurrPos += 1) > 41) { // Если достигли конца служебной области
Floppy[Numb].CurrPos = 0; // Позицируемся на начало
Floppy[Numb].PosType = 1; // сектора
}
}
void FASTC PPU_WrW_FDD_STATE(UINT16 Data) { // Регистр состояния Floppy-диска
UINT8 Numb;
if (Data & 0x400) { // Если активен бит выбора дисковода (REZ)
Numb = 3 - (Data & 0x3); // Numb - номер дисковода (0..3)
if ((!(PPU_FDD_STATE & 0x200)) && (Data & 0x200)) { // Если смена бита WM 0->1,
Floppy[Numb].Mode = 2; // то включаем режим записи
Floppy[Numb].CurrPos = -1; // Текущая позиция в секторе -1 (для пропуска
// первого синхрослова $FBA1
}
PPU_FDD_STATE = Data;
if (PPU_FDD_STATE & 0x10) // Если включен двигатель дисковода
Floppy[Numb].Motor = 1; // то Motor = 1, иначе Motor = 0
else Floppy[Numb].Motor = 0;
Floppy[Numb].Side = (PPU_FDD_STATE & 0x20) >> 5; // Выбор номера головки
if (PPU_FDD_STATE & 0x80) { // Если установлен бит шага (ST), то
PPU_FDD_STATE &= 0xFF7F; // Сбросить бит шага
Floppy[Numb].Mode = 0; // Режим 'перемещение' (для цветовой индикации)
if (PPU_FDD_STATE & 0x40) { // Если направление шага к центру, то
if (Floppy[Numb].Track < MaxTrack)
Floppy[Numb].Track += 1;
else printf("Wrong Track: %d\n", Floppy[Numb].Track + 1);
}
else { // Иначе направление от центра
if (Floppy[Numb].Track > 0)
Floppy[Numb].Track -= 1;
}
}
if (PPU_FDD_STATE & 0x100) { // Если установлен бит инициализации (GOR)
Floppy[Numb].Ready = 0; // Сбросить бит готовности данных
}
}
return;
}
void FASTC PPU_WrW_FDD_DATA(UINT16 Data) { // Регистр данных Floppy-диска
UINT8 Numb = 3 - (PPU_FDD_STATE & 0x3); // Numb - номер дисковода (0..3)
if (Floppy[Numb].Mode == 2) { // Если активен режим записи
if ((SINT32)Floppy[Numb].CurrPos >= 0) { // Если позиция внутри сектора >= 0
*(UINT16*)(Floppy[Numb].ImagePTR // Записать слово на образ
+ ((Floppy[Numb].Track << 1) + Floppy[Numb].Side) * 5120
+ (Floppy[Numb].CurrPos << 1)
+ Floppy[Numb].Sector * 512) = Data;
}
if ((Floppy[Numb].CurrPos += 1) > 255) { // Если достигли конца сектора
Floppy[Numb].CurrPos = 0; // Позицируемся на начало
Floppy[Numb].PosType = 0; // межсекторного пространства
if ((Floppy[Numb].Sector +=1) > 9) // Перейти к следующему сектору
Floppy[Numb].Sector = 0; // Если достигли сектора 10, то переход к сектору 0
Floppy[Numb].ControlSp[22] = (Floppy[Numb].Track << 8) | // Прописываем в служебное поле
Floppy[Numb].Side; // номер трека / головки
Floppy[Numb].ControlSp[23] = ((Floppy[Numb].Sector + 1) << 8) | // номер сектора / длина
2; //
Floppy[Numb].Mode = 0; // Режим 'бездействие'
}
}
return;
}