User Tag List

Показано с 1 по 10 из 336

Тема: Эмулятор Союз-Неон ПК-11/16 - EmuStudio

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #16

    Регистрация
    08.10.2005
    Адрес
    Москва
    Сообщений
    14,394
    Спасибо Благодарностей отдано 
    1,702
    Спасибо Благодарностей получено 
    2,219
    Поблагодарили
    873 сообщений
    Mentioned
    69 Post(s)
    Tagged
    1 Thread(s)

    По умолчанию

    Вот, как у меня FDD сделан в эмуляторе.

    Понятно, что я его не эмулировал целиком, а только то, что было не обходимо для работоспособности FDD.
    И как это работает, я уже не помню)

    Скрытый текст


    Код:
    static struct {								// Определить структуру, описывающую дисководы
    			   UINT8 Track,					// Номер трека (00..79, при over-позицировании > 79)
    					 Side,					// Сторона (0 - нижняя головка, 1 - верхняя головка)
    				     Motor,					// Мотор (00 - включен, иначе выключен)
    					 PrevMotor,				// Предыдущее состояние мотора (для иконок дискет)
    					 Mode,					// Режим (00 - нет чтения/записи, 01 - чтение, 02 - запись)
    					 Sector;				// Текущий сектор (0..9)
    			   UINT8 *ImagePTR;				// Указатель на образ диска (образ 819200 байт)
    			  } Floppy[2];
    
    static UINT8 FDD_DataBuf[2048];				// Буфер для сектора HDD/FDD
    static UINT32 FDD_DataBufAdr;				// Указатель адреса в буферном ОЗУ контроллера HDD/FDD
    static UINT8 FDD_ComDim[256];				// Буфер для команд ввода-вывода
    static UINT8 FDD_ComAdr;					// Указатель на текущий адрес в массиве данных ввода-вывода
    static UINT8 FDD_ComLen;					// Оставшееся число байт до конца пакета
    static UINT8 *FDD_DataAdr;					// Указатель на массив сектора в памяти
    static UINT32 FDD_DataPTR = 0;				// Позиция внутри сектора 0..511
    
    static const MaxTrack = 79;					// Максимальный разрешенный номер трека
    
    static UINT8 FD_CSR = 0x80;					// Регистр статуса FDD
    											// Бит 7: 0 - контроллер не готов, 1 - контроллер готов
    											// Бит 6: 0 - обмен по чтению, 1 - обмен по записи
    
    static char FDDImageNames[4][1024];			// Имена файлов для 4-х образов дисков
    
    
    
    
    static UINT16 FASTC	CPU_RdW_HD_BUF(void)				// hd.buf
    {	
    	UINT8 Byte;
    
    	//printf("Read word from CPU register HD.BUF from location PC=0x%X\n",
    	//	   (UINT16)CPU->l.PC);
    
    	Byte = FDD_DataBuf[FDD_DataBufAdr & 0x07FF];		// Чтение байта из буферного ОЗУ контроллера HDD/FDD
    	
    	FDD_DataBufAdr++;
    
    	return(Byte);
    }
    
    
    
    static UINT16 FASTC	CPU_RdW_HD_CSR(void)				// hd.csr
    {				
    	//printf("Read word from CPU register HD.CSR from location PC=0x%X\n",
    	//	   (UINT16)CPU->l.PC);
    
    	FDD_DataBufAdr = 0;									// [T] Сброс адресного указателя буферного ОЗУ
    														// (пока что считаем, что он сбрасывается при чтении hd.csr
    
    	return(0x41);										// Первичная готовность да, вторичная - нет
    }
    
    
    
    
    
    static UINT16 FASTC	CPU_RdW_FD_BUF(void)					// fd.buf
    {		
    	UINT8 Byte = 0;
    	
    	Byte = FDD_ComDim[FDD_ComAdr++];						// Взять байт из буфера
    
    	if (FDD_ComAdr == FDD_ComLen)							// Если конец пакета, то
    	{	
    		switch (FDD_ComDim[0])
    		{
    			case 0x08:										// Sence Interrupt Status (Опрос состояния)
    //						FDDNum = FDD_ComDim[1] & 0x3;		// FDDNum - номер дисковода
    						
    //						Floppy[FDDNum].Track = 0;			// Установиться на трек 00
    
    						FD_CSR = 0x80;						// Установить готовность записи данных в контроллер
    						FDD_ComAdr = 0;						// Обнулить указатель адреса в буфере обмена
    
    						break;
    
    			case 0x45:										// Write Data MFM
    						
    						FD_CSR = 0x80;						// Установить готовность записи данных в контроллер
    						FDD_ComAdr = 0;						// Обнулить указатель адреса в буфере обмена
    						break;
    
    			case 0x46:										// Read Data MFM
    						
    						FD_CSR = 0x80;						// Установить готовность записи данных в контроллер
    						FDD_ComAdr = 0;						// Обнулить указатель адреса в буфере обмена
    						break;
    
    			default:   
    						printf ("WARNING FDD 002!!!\n");
    		}
    	}
    
    	//printf("Read word 0x%02X from CPU register FD.BUF from location PC=0x%X\n",
    	//	   Byte, (UINT16)CPU->l.PC);
    
    	return(Byte);
    }
    
    
    
    static void FASTC	CPU_WrW_HD_CSR(UINT16 Data)		// [T] hd.csr
    {		
    	//printf("Write word 0x%04X to unrealized CPU register HD.CSR from location PC = 0x%X\n",
    	//	   Data, (UINT16)CPU->l.PC);
    
    	if (Data == 0x0010)								// [T] Если записали 0x0010 в порт, то
    		PIC_IRQM |= 0x02;							// дать запрос на прерывание от FDD/HDD
    													// (чтобы контроллер отстал и не тормозил)
    	return;
    }
    
    
    static void FASTC	CPU_WrW_FD_BUF(UINT16 Data)		// [T] fd.buf
    {	
    	UINT8 Byte = (UINT8)Data,
    		  FDDNum,
    		  BCnt;
    
    	//printf("Write word 0x%04X to CPU register FD.BUF from location PC = 0x%X\n",
    	//	   Data, (UINT16)CPU->l.PC);
    
    	if (FDD_ComAdr == 0)									// Если адрес в буфере обмена = 0, то код команды
    	{
    
    		switch (Byte)
    		{
    			case 0x03:										// Specify (Задание параметров)
    //					   printf("FDD Command: Specify\n");
    
    					   FDD_ComLen = 3;						// Длина команды
    		
    					   FDD_ComDim[0] = Byte;				// Записать команду в начало буфера
    					   break;
    
    			case 0x07:										// Recalibrate (Трек-0)
    					   //printf("FDD Command: Track-0\n");
    
    					   FDD_ComLen = 2;						// Длина команды
    		
    					   FDD_ComDim[0] = Byte;				// Записать команду в начало буфера
    					   break;
    
    			case 0x08:										// Sence Interrupt Status (Опрос состояния)
    //					   printf("FDD Command: Sence Status\n");
    
    					   FDD_ComLen = 3;						// Длина команды
    		
    					   FDD_ComDim[0] = Byte;				// Записать команду в начало буфера
    
    					   FDD_ComDim[1] = 0x20;				// Записать байт корректного результата в буфер ($20)
    					   FDD_ComDim[2] = 0;					// (Остальные байты не опрашиваются)
    
    					   FD_CSR = 0xC0;						// Установить готовность чтения данных из контроллера
    					   break;
    
    			case 0x0F:										// Seek (Перемещение)
    //					   printf("FDD Command: Seek\n");
    
    					   FDD_ComLen = 3;						// Длина команды
    		
    					   FDD_ComDim[0] = Byte;				// Записать команду в начало буфера
    					   break;
    
    			case 0x45:										// Write Data MFM
    //					   printf("FDD Command: Write Data MFM\n");
    
    					   FDD_ComLen = 9;						// Длина команды
    		
    					   FDD_ComDim[0] = Byte;				// Записать команду в начало буфера
    					   break;
    
    			case 0x46:										// Read Data MFM
    //					   printf("FDD Command: Read Data MFM\n");
    
    					   FDD_ComLen = 9;						// Длина команды
    		
    					   FDD_ComDim[0] = Byte;				// Записать команду в начало буфера
    					   break;
    
    			default:
    					   printf("WARNING! FDD Command 0x%02X unrealized!\n", Byte);
    		}
    
    		FDD_ComAdr++;										// Перейти к следующей позиции в буфере
    
    	}
    
    	else													// Иначе блок данных команды
    	{
    		FDD_ComDim[FDD_ComAdr++] = Byte;					// Записать байт в буфер
    
    		if (FDD_ComAdr == FDD_ComLen)						// Если конец пакета, то
    		{	
    
    			switch (FDD_ComDim[0])
    			{
    				case 0x03:									// Specify (Задание параметров)
    
    						   // Данные игнорируем				// [T]
    
    						   FDD_ComAdr = 0;					// Обнулить указатель адреса в буфере обмена
    						   break;
    
    				case 0x07:									// Recalibrate (Трек-0)
    						   FDDNum = FDD_ComDim[1] & 0x3;	// FDDNum - номер дисковода
    						   
    						   Floppy[FDDNum].Track = 0;		// Установиться на трек 00
    
    						   PIC_IRQM |= 0x02;				// Запрос на прерывание от FDD/HDD
    						   FDD_ComAdr = 0;					// Обнулить указатель адреса в буфере обмена
    						   break;
    
    				case 0x0F:									// Seek (Перемещение)
    						   FDDNum = FDD_ComDim[1] & 0x3;	// FDDNum - номер дисковода
    						   
    						   Floppy[FDDNum].Track = FDD_ComDim[2]; // Установиться на трек nn
    
    						   //printf("FDD - Seek to track %d\n", Floppy[FDDNum].Track);
    
    						   PIC_IRQM |= 0x02;				// Запрос на прерывание от FDD/HDD
    						   FDD_ComAdr = 0;					// Обнулить указатель адреса в буфере обмена
    						   break;
    
    				case 0x45:									// Write Data MFM
    						   FDDNum = FDD_ComDim[1] & 0x3;	// FDDNum - номер дисковода
    						   
    						   Floppy[FDDNum].Track = FDD_ComDim[2]; // Трек
    						   Floppy[FDDNum].Side = (FDD_ComDim[1] >> 2) & 1; // Сторона
    						   Floppy[FDDNum].Sector = FDD_ComDim[4]; // Сектор
    
    						   if (Floppy[FDDNum].Track > MaxTrack) // Ограничить максимальный номер трека
    							   Floppy[FDDNum].Track = MaxTrack;
    
    						   if (Floppy[FDDNum].Sector > 10)	// Ограничить максимальный номер сектора (1..10)
    							   Floppy[FDDNum].Sector = 10;
    
    						   FDD_ComDim[9] = 0x20;			// Записать байт корректного результата в буфер ($20)
    						   FDD_ComDim[10] = 0;				// (Остальные байты не опрашиваются)
    						   FDD_ComDim[11] = 0;				//
    						   FDD_ComDim[12] = 0;				//
    						   FDD_ComDim[13] = 0;				//
    						   FDD_ComDim[14] = 0;				//
    						   FDD_ComDim[15] = 0;				//
    
    						   BCnt = 4 - (FD_CNT & 0x3);		// BCnt - счетчик секторов для записи за один раз
    
    						   //printf("FDD - Write MFM: Drive: %d, Track: %d, Head: %d, Sector: %d, Len: %d\n",
    							  //    FDDNum, FDD_ComDim[2], FDD_ComDim[3], FDD_ComDim[4], BCnt); 
    
    						   // Самой записи пока нет
    
    						   FDD_ComLen += 7;					// Увеличить длину команды на 7 байт (ответ контроллера)
    
    						   PIC_IRQM |= 0x02;				// Запрос на прерывание от FDD/HDD
    						   FD_CSR = 0xC0;					// Установить готовность чтения данных из контроллера
    						   break;
    
    				case 0x46:									// Read Data MFM
    						   FDDNum = FDD_ComDim[1] & 0x3;	// FDDNum - номер дисковода
    						   
    						   Floppy[FDDNum].Track = FDD_ComDim[2]; // Трек
    						   Floppy[FDDNum].Side = (FDD_ComDim[1] >> 2) & 1; // Сторона
    						   Floppy[FDDNum].Sector = FDD_ComDim[4]; // Сектор
    
    						   if (Floppy[FDDNum].Track > MaxTrack) // Ограничить максимальный номер трека
    							   Floppy[FDDNum].Track = MaxTrack;
    
    						   if (Floppy[FDDNum].Sector > 10)	// Ограничить максимальный номер сектора (1..10)
    							   Floppy[FDDNum].Sector = 10;
    
    						   FDD_ComDim[9] = 0x20;			// Записать байт корректного результата в буфер ($20)
    						   FDD_ComDim[10] = 0;				// (Остальные байты не опрашиваются)
    						   FDD_ComDim[11] = 0;				//
    						   FDD_ComDim[12] = 0;				//
    						   FDD_ComDim[13] = 0;				//
    						   FDD_ComDim[14] = 0;				//
    						   FDD_ComDim[15] = 0;				//
    
    						   BCnt = 4 - (FD_CNT & 0x3);		// BCnt - счетчик секторов для чтения за один раз
    
    															// Копируем сектор в буферное ОЗУ контроллера
    						   memcpy(FDD_DataBuf,
    							      (Floppy[FDDNum].ImagePTR +
    								   ((Floppy[FDDNum].Track << 1) + (Floppy[FDDNum].Side & 0x1)) * 5120 +
    								   ((Floppy[FDDNum].Sector - 1) * 512)),
    							      512 * BCnt);
    
    						   //printf("FDD - Read MFM: Drive: %d, Track: %d, Head: %d, Sector: %d, Len: %d\n",
    							  //    FDDNum, FDD_ComDim[2], FDD_ComDim[3], FDD_ComDim[4], BCnt); 
    
    						   FDD_ComLen += 7;					// Увеличить длину команды на 7 байт (ответ контроллера)
    
    						   PIC_IRQM |= 0x02;				// Запрос на прерывание от FDD/HDD
    						   FD_CSR = 0xC0;					// Установить готовность чтения данных из контроллера
    						   break;
    
    				default:   
    						   printf ("WARNING FDD 001!!!\n");
    			}
    		}
    	}
    
    
    
    	return;
    }
    
    
    static void FASTC	CPU_WrW_FD_CNT(UINT16 Data)		// [T] fd.cnt
    {	
    	//printf("Write word 0x%04X to CPU register FD.CNT from location PC = 0x%X\n",
    	//	   Data, (UINT16)CPU->l.PC);
    
    	FD_CNT = (UINT8)Data;
    
    	if (Data == 0x10)								// Инициализация регистров контроллера?
    	{
    		FD_CSR = 0x80;								// Установить готовность записи данных в контроллер
    		FDD_ComAdr = 0;								// Обнулить указатель адреса в буфере обмена
    	}
    
    	if ((Data >= 0) && (Data < 4))					// Если число в диапазоне от 0..3, то это 
    	{												// число секторов (блоков) для чтения в буферное ОЗУ контроллера
    		;
    	}
    
    
    	return;
    }
    [свернуть]

    Эти 2 пользователя(ей) поблагодарили Titus за это полезное сообщение:

    Alex_K(01.01.2023), nzeemin(01.01.2023)

  2. #16
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Эмулятор УКНЦ - EmuStudio
    от Titus в разделе Эмуляторы отечественных компьютеров
    Ответов: 1198
    Последнее: 07.05.2025, 13:34
  2. EmuStudio-ZX
    от Titus в разделе Эмуляторы
    Ответов: 726
    Последнее: 16.03.2025, 19:38
  3. Эмулятор ТИА-МЦ-1 EmuStudio
    от Titus в разделе Эмуляторы отечественных компьютеров
    Ответов: 107
    Последнее: 20.09.2024, 21:03
  4. Эмулятор МС-0515 - EmuStudio
    от Titus в разделе Эмуляторы отечественных компьютеров
    Ответов: 143
    Последнее: 09.02.2023, 10:44
  5. ПК-11 'Союз-Неон'
    от Keeper в разделе ДВК, УКНЦ
    Ответов: 12
    Последнее: 16.10.2013, 05:07

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •