![Цитата](images/styles/asdialup/misc/quote_icon.png)
Сообщение от
andykarpov
А где на исходники проекта можно посмотреть?
Как там порт чтения клавиатуры и магнитофона реализованы?
Можно, но я пока рисую на AHDL ![Smile](images/smilies/dizzy_smile.gif)
Код:
----------------------------------------------------------------------------------------------------------------------------
-- Описание: Прошивка микросхемы CPLD DD1 (модуль EPM3256AQC208_IGP1)
-- Проект: ZXM-Jasper
-- Автор: Тарасов М.Н. (Mick)
-- Тип CPLD: EPM3256AQC208
-- Версия: v1.00 - 2017
----------------------------------------------------------------------------------------------------------------------------
TITLE "ZXM-Jasper System Array Logic";
FUNCTION 2mux1 (a, b, sel) RETURNS (y);
SUBDESIGN MODULE_CPLD
(
-- Входная тактовая частота CLK
CLK_14MHZ : INPUT;
-- Сигналы управления RAM памятью
MA[16..0] : OUTPUT;
MD[7..0] : BIDIR;
WR_RAM : OUTPUT;
CS_RAML : OUTPUT;
CE_RAM2 : OUTPUT;
-- Выходные сигналы видео формирователя
VD[7..0] : OUTPUT;
HS : OUTPUT;
VS : OUTPUT;
GI : OUTPUT;
-- Сигналы управления ROM памятью
ROM_A14 : OUTPUT;
ROM_A15 : OUTPUT;
RD_ROM : OUTPUT;
WR_ROM : OUTPUT;
CS_ROM : OUTPUT;
-- Сигналы управления с CPU
CA[15..0] : INPUT;
CD[7..0] : BIDIR;
C_CLK : OUTPUT;
C_IORQ : INPUT;
C_MREQ : INPUT;
C_M1 : INPUT;
C_RD : INPUT;
C_WR : INPUT;
C_RFSH : INPUT;
-- Общие сигналы
C_RESET : INPUT;
C_MAGIC : INPUT;
C_IORQGE : INPUT;
C_INT : OUTPUT;
C_NMI : OUTPUT;
C_BLK : INPUT; --OUTPUT;
C_BUSRQ : INPUT; --OUTPUT;
C_WAIT : INPUT; --OUTPUT;
C_IODOS : INPUT; --OUTPUT;
C_DOS : OUTPUT;
-- Сигналы YM2149
AYCLK : OUTPUT;
BC1 : OUTPUT;
BDIR : OUTPUT;
-- Сигналы порта FE
TAPE_IN : INPUT;
TAPE_OUT : OUTPUT;
BEEP : OUTPUT;
-- Сигналы выбора джойстика
RD_1F : OUTPUT;
-- Скандаблер
PA[14..0] : OUTPUT; -- адреса знакомест
VWR : OUTPUT; -- сигнал записи в видеобуфер
PD[5..0] : BIDIR; -- данные
-- Сигналы клавиатуры
KBD_CS : INPUT;
KBD_CLK : INPUT;
KBD_DI : INPUT
)
VARIABLE
Sync_count[2..0] : DFF; -- 4-х разрядный счетчик, сигналы TI, H0, H1
Clk_reg : DFF;--системный регистр
CLKZ : NODE;-- частота процессора
H0M : NODE;-- частота селектора памяти
H1M : NODE;-- частота селектора памяти
VCLK : NODE; -- опорная частота видеочетчиков
HSync_count[6..0]: DFF; -- 6-и разрядный счетчик строчной разверкти, сигналы H3..H8
HReset : NODE; -- сброс счетчиков строчной развертки
HBlank : NODE; -- сигнал гашения видеосигнала строчный
HBlank1 : NODE; -- сигнал гашения видеосигнала строчный
HBlank2 : NODE; -- сигнал гашения видеосигнала строчный
HBlank3 : DFF; -- сигнал гашения видеосигнала строчный
HBorder : NODE; -- сигнал строчного бордера
HSync : DFF; -- строчный синхроимпульс
HSync1 : DFF; -- синхроимпульс счета кадровых счетчиков
VSync_count[8..0] : DFF; -- 10-и разрядный счетчик кадровый развертки, сигналы V0..V9
VReset : NODE; --сброс счетчиков кадровой развертки
VSync : DFF; -- кадровый синхроимпульс
VBorder : NODE; -- сигнал кадрового бордера
Border_sync : DFF; -- строб бордера
Int_sync : DFF; -- строб прерывания
Int_count[3..0] : DFF; -- 4-и разрядный счетчик длительности прерывания
Flash_count[4..0] : DFF; -- 6-и разрядный счетчик мерцания, сигнал FLASH
REG_rddata[7..0] : TRI; -- буфер чтения памяти
DATA_CPU[7..0] : TRI_STATE_NODE;
-- Сигналы управления памятью
WR_Buf : LCELL; -- запись в буферный регистр
VA[4..0] : NODE; -- адрес видео памяти
RA[2..0] : NODE; -- адрес видео памяти
Sel_A45 : NODE; -- доступ к ОЗУ
Ram_write_r : DFF; -- запись в ОЗУ
Ram_wrdata[7..0]: TRI; -- буфер записи в ОЗУ
Ram_buf[7..0] : DFF;
Ram_smx : NODE; -- страницы ОЗУ
RD_MEMORY : LCELL;
ROM_SEL : NODE;
-- Сигналы управления видеоформирователем
WRSCR : LCELL; -- сигнал защелкивания видеоинформации
Reg_inf[7..0] : DFF; -- регистр видеоинформации
Reg_pix[7..0] : DFF; -- регистр пикселей (промежуточный)
Reg_atr[7..0] : DFF; -- регистр цвета
Pix_inf : LCELL; -- видеоинформация
Reg_vid[5..0] : DFF; -- регистр видео выходной
ColourADR[3..0] : NODE;
-- Управляющие сигналы
IO_ENABLE : NODE; -- доступ к портам
IO_RD : LCELL; -- чтение из портов
IO_WR : LCELL; -- запись в порты
Sel_code : NODE; -- выбор ПЗУ TRDOS
Sel_3dxx : NODE; -- выбор ПЗУ TRDOS
DOS_r : JKFF; -- выбор ПЗУ TRDOS
NMI_r : DFF; -- выбор ПЗУ TRDOS
DOS_En : LCELL; --доступ к контроллеру дисковода
RDFE_Sel : LCELL; -- выбор клавиатуры
-- Регистр порта xxFEh
WR_FE : LCELL;
Border_Color_r[2..0] : DFF;
Tape_r : DFF;
Beep_r : DFF;
-- Регистр порта 7FFDh
Sel_7FFD : NODE;
WR_7FFD : LCELL;
RAM0_Page_r[2..0] : DFF; -- основные страницы 128кб
SCR128_r : DFF; --экран в 4000h или C000h (3 - бит)
ROM128_r : DFF; -- 128 ПЗУ (4 - бит)
BLK_Port_r : DFF; -- блокировка записи в порт (5 - бит)
-- Скандаблер
VHReset : NODE;
VHBlank : NODE;
SHReset : NODE;
VWR_strobe : NODE; -- запись в буфер
MUX_strobe : DFF; -- счетчик переключения буферов
MUX_data : LCELL; -- триггер конца строки
WHSync_count[6..0] : DFF; -- счетчик знакомест
VHSync_count[2..0] : DFF; -- счетчик знакомест
SHSync_count[2..0] : DFF; -- счетчик знакомест
VD_reg[5..0] : DFF; -- регистр видео
REG_wscan[5..0] : TRI;
RH : NODE;
-- интерфейс клавиатуры
KBD_save_en : NODE;
KBD_count[3..0] : DFFE;
KBD_shift_in[7..0] : DFF;
KBD_regA8[4..0] : DFFE;
KBD_regA9[4..0] : DFFE;
KBD_regA10[4..0] : DFFE;
KBD_regA11[4..0] : DFFE;
KBD_regA12[4..0] : DFFE;
KBD_regA13[4..0] : DFFE;
KBD_regA14[4..0] : DFFE;
KBD_regA15[4..0] : DFFE;
KBD_rddata[7..0] : TRI;
BEGIN
------------------------------------------------------------------------------------
-- Синхрогенератор
------------------------------------------------------------------------------------
-- Clock frequency 14.000 MHz
-- "256 x 192 Screen"
-- Line frequency 15625 Hz
-- Field frequency 50 Hz
-- Sync polarity: H negative, V negative
-- Scan type: non interlaced.
------------------------------------------------------------------------------------
-- Системные сигналы
------------------------------------------------------------------------------------
Sync_count[].clk = CLK_14MHZ; -- Системные сигналы TI, H0, H1, 2
Sync_count[].d = Sync_count[].q+1;
VCLK = !(Sync_count[].q == B"111");
------------------------------------------------------------------------------------
-- Строчная развертка
------------------------------------------------------------------------------------
-- One line:
-- 32 pixels horizontal sync
-- 32 pixels back porch
-- 64 pixels left border
-- 256 pixels video
-- 64 pixels right border
------------------------------------------------------------------------------------
-- 448 pixels total per line
------------------------------------------------------------------------------------
-- Реализация
------------------------------------------------------------------------------------
-- 32 видимая часть
-- 8 правый бордер
-- 4 начало гасящего импульса
-- 4 строчный импульс
-- 8 левый бордер
-- =
-- 56 сброс счетчиков строчной развертки
------------------------------------------------------------------------------------
HSync_count[].clk = VCLK; -- Сигналы строчной развертки H3, H4, H5, H6, H7, BC
HSync_count[].d = HSync_count[].q+1;
HSync_count[].clrn = !HReset;
HReset = (HSync_count[6..4].q == B"111"); -- сброс счетчиков в конце второй строки VGA
HBorder = HSync_count[6].q; -- сигнал строчного бордера на второй строке VGA
HBlank1 = !(HSync_count[6..3].q == B"0101"); -- гасящий импульс на первой VGA строке
HBlank2 = !(HSync_count[6..3].q == B"1100"); -- гасящий импульс на второй VGA строке
HBlank = HBlank1 & HBlank2;
HSync.clk = VCLK;
HSync.d = HBlank # HSync_count[2].q;
HBlank3.clk = !(HSync_count[6..0].q ==B"1010000");
HBlank3.d = GND;
HBlank3.prn = !(HSync_count[6..0].q == B"1100101");
------------------------------------------------------------------------------------
-- Кадровая развертка
------------------------------------------------------------------------------------
-- One field:
-- 16 lines vertical sync = porch
-- 56 lines top border
-- 192 lines video
-- 48 lines bottom border
------------------------------------------------------------------------------------
-- 312 lines total per field
------------------------------------------------------------------------------------
-- Реализация
------------------------------------------------------------------------------------
-- 192 видимая часть
-- 48 нижний бордер
-- 16 кадровый импульс = гасящий импульс
-- 56 верхний бордер
-- =
-- 312 сброс счетчиков кадровой развертки
------------------------------------------------------------------------------------
HSync1.clk = VCLK;
HSync1.d = (HSync_count[6..0] == B"1001101");
VSync_count[].clk = HSync1.q; -- Сигналы кадровой развертки V0...V7
VSync_count[].d = VSync_count[].q+1;
VSync_count[].clrn = !VReset;
VReset = (VSync_count[8..3].q == B"101000");-- сброс на 320 строке
VBorder = VSync_count[8].q # (VSync_count[7].q & VSync_count[6].q); -- сигнал BK = V8 # (V7 & V6)
VSync.clk = VCLK;
VSync.d = !(VSync_count[8..4].q == B"01111");
------------------------------------------------------------------------------------
-- Счетчики мерцания
------------------------------------------------------------------------------------
Flash_count[].clk = !VSync.q; --Сигналы счетчиков мерцания BK/, FLASH
Flash_count[].d = Flash_count[].q+1;
------------------------------------------------------------------------------------
-- Строб бордера
------------------------------------------------------------------------------------
Border_sync.d = !(VBorder # HBorder);
Border_sync.clk = HSync_count[1].q;
------------------------------------------------------------------------------------
-- Счетчик длительности прерывания
------------------------------------------------------------------------------------
Int_count[].clk = VCLK;
Int_count[].d = Int_count[].q+1;
Int_count[].clrn = !Int_sync.q;
------------------------------------------------------------------------------------
-- Сигнал прерывания
-- Примечание: прерывание генерится с частотой 48Гц
------------------------------------------------------------------------------------
Int_sync.clk = !VSync.q; -- прерывание на 256 импульсе
Int_sync.d = GND;
Int_sync.prn = !(Int_count[3..0].q == B"1111");
------------------------------------------------------------------------------------
-- Сигнал прерывания
-- временно на 121 ногу сигнал EXT1, был 117
------------------------------------------------------------------------------------
C_INT = Int_sync.q;
------------------------------------------------------------------------------------
-- Сигнал синхронизации
------------------------------------------------------------------------------------
HS = HSync.q;
------------------------------------------------------------------------------------
-- Сигнал разрешения SCART
------------------------------------------------------------------------------------
VS = VSync.q;
------------------------------------------------------------------------------------
-- Сигнал гашения
------------------------------------------------------------------------------------
GI = GND;
------------------------------------------------------------------------------------
-- Видеоформирователь
------------------------------------------------------------------------------------
-- Стробирующие сигналы захвата информации
------------------------------------------------------------------------------------
WRSCR = !(Sync_count[1].q & Sync_count[2].q & HSync_count[0].q);
------------------------------------------------------------------------------------
-- Сдвиговый регистр пикселей
------------------------------------------------------------------------------------
Reg_pix[].clk = HSync_count[0].q; -- сигналы H2
Reg_pix[].d = MD[];
------------------------------------------------------------------------------------
-- Сдвиговый регистр пикселей
------------------------------------------------------------------------------------
Reg_inf[].clk = Sync_count[0].q; -- сигнал 7MHZ
IF WRSCR !=0 THEN Reg_inf[].d = (Reg_inf[7-1..0].q,GND);
ELSE Reg_inf[].d = Reg_pix[];
END IF;
------------------------------------------------------------------------------------
-- Регистр атрибутов
------------------------------------------------------------------------------------
Reg_atr[].clk = WRSCR;
Reg_atr[].d = MD[];
------------------------------------------------------------------------------------
-- Мерцание знакоместа
------------------------------------------------------------------------------------
Pix_inf = Reg_inf[7].q $ (Flash_count[4].q & Reg_atr[7].q);
------------------------------------------------------------------------------------
-- Адрес палитры
------------------------------------------------------------------------------------
IF Border_sync.q ==0 THEN
ColourADR[0] = Border_Color_r[0].q;
ColourADR[1] = Border_Color_r[1].q;
ColourADR[2] = Border_Color_r[2].q;
ColourADR[3] = GND;
ELSE
IF Pix_inf ==0 THEN
ColourADR[0] = Reg_atr[3].q; --Blue
ColourADR[1] = Reg_atr[4].q; --Red
ColourADR[2] = Reg_atr[5].q; --Green
ColourADR[3] = Reg_atr[6].q; --Bright
ELSE
ColourADR[0] = Reg_atr[0].q; --Blue
ColourADR[1] = Reg_atr[1].q; --Red
ColourADR[2] = Reg_atr[2].q; --Green
ColourADR[3] = Reg_atr[6].q; --Bright
END IF;
END IF;
------------------------------------------------------------------------------------
-- Вывод видеоинформации
------------------------------------------------------------------------------------
Reg_vid[].clk = Sync_count[0].q; -- сигнал 7MHZ
Reg_vid[].clrn = HBlank3.q & VSync.q;
Reg_vid[0].d = ColourADR[0]; -- Blue0
Reg_vid[1].d = ColourADR[0] & ColourADR[3]; -- Blue1
Reg_vid[2].d = ColourADR[1]; -- Red0
Reg_vid[3].d = ColourADR[1] & ColourADR[3]; -- Red1
Reg_vid[4].d = ColourADR[2]; -- Green0
Reg_vid[5].d = ColourADR[2] & ColourADR[3]; -- Green1
------------------------------------------------------------------------------------
-- Системные сигналы
------------------------------------------------------------------------------------
-- C_BUSRQ = VCC;
-- C_WAIT = VCC;
------------------------------------------------------------------------------------
-- Сигнал формирование частоты процессора
-- Примечание: процессор на частоте 3,5МГц(NORMAL)
------------------------------------------------------------------------------------
H0M = Sync_count[1].q; -- H0
H1M = Sync_count[2].q; -- H1
Clk_reg.d = Sync_count[1].q;
Clk_reg.clk = Sync_count[0].q;
CLKZ = !H0M;--Clk_reg.q;
C_CLK = CLKZ;
------------------------------------------------------------------------------------
-- Управление памятью RAM
------------------------------------------------------------------------------------
-- Сигнал записи в буферный регистр TI =1 и H0 =0
------------------------------------------------------------------------------------
WR_Buf = H0M & !H1M; -- сигнал WRBUF
------------------------------------------------------------------------------------
-- Запись в буферный регистр
------------------------------------------------------------------------------------
Ram_buf[].d = MD[];
Ram_buf[].clk = !WR_Buf;
------------------------------------------------------------------------------------
-- Сигнал мультиплексирования страниц ОЗУ
------------------------------------------------------------------------------------
Ram_smx = CA[15] and CA[14]; -- сигнал SMX = A15 & A14
------------------------------------------------------------------------------------
-- Выбор памяти ОЗУ
------------------------------------------------------------------------------------
Sel_A45 = CA[15] # CA[14]; -- сигнал A45 = A15 # A14 # BLK
------------------------------------------------------------------------------------
-- Сигнал записи в память
------------------------------------------------------------------------------------
Ram_write_r.d = Sel_A45 & !C_MREQ & C_RD & C_RFSH;
Ram_write_r.clrn = !H1M;
Ram_write_r.clk = !CLKZ;--!Clk_reg.q;
Ram_write_r.prn = VCC;
------------------------------------------------------------------------------------
-- Запись в память
------------------------------------------------------------------------------------
WR_RAM = !Ram_write_r.q;
Ram_wrdata[].in = CD[];
Ram_wrdata[].oe = Ram_write_r.q;
MD[] = Ram_wrdata[].out;
------------------------------------------------------------------------------------
-- Формирование адресов видеоконтроллера VА
------------------------------------------------------------------------------------
IF HSync_count[0].q ==0 THEN -- сигнал H2
VA[0] = VSync_count[0].q;
VA[1] = VSync_count[1].q;
VA[2] = VSync_count[2].q;
VA[3] = VSync_count[6].q;
VA[4] = VSync_count[7].q;
ELSE
VA[0] = VSync_count[6].q;
VA[1] = VSync_count[7].q;
VA[2] = GND;
VA[3] = VCC;
VA[4] = VCC;
END IF;
------------------------------------------------------------------------------------
-- Формирование адресов RА
------------------------------------------------------------------------------------
IF Ram_smx ==0 THEN -- выборк окна в адресах 0x000..0xBFFF
RA[0] = CA[14];
RA[1] = CA[15];
RA[2] = CA[14];
ELSE
RA[0] = RAM0_PAGE_r[0].q; -- сигнал Page0
RA[1] = RAM0_PAGE_r[1].q; -- сигнал Page1
RA[2] = RAM0_PAGE_r[2].q; -- сигнал Page2
END IF;
------------------------------------------------------------------------------------
-- Формирование адресов и выбор микросхемы памяти
------------------------------------------------------------------------------------
IF H1M ==0 THEN
MA[13..0] = CA[13..0];
MA[16..14] = RA[2..0];
ELSE
MA[4..0] = HSync_count[5..1]; -- сигналы H3...H7
MA[5] = VSync_count[3].q; -- сигнал V4
MA[6] = VSync_count[4].q; -- сигнал V5
MA[7] = VSync_count[5].q; -- сигнал V6
MA[12..8] = VA[4..0]; -- сигналы VA0...VA4
MA[13] = GND; -- сигнал 0
MA[14] = VCC; -- сигнал 1
MA[15] = SCR128_r.q; -- сигнал SCR128
MA[16] = VCC; -- сигнал 1
END IF;
CS_RAML = GND;
CE_RAM2 = VCC;
------------------------------------------------------------------------------------
-- Управление памятью ROM
------------------------------------------------------------------------------------
-- Формирование управляющих сигналов ROM памяти
------------------------------------------------------------------------------------
ROM_A14 = ROM128_r.q # !DOS_en; -- сигнал RA14 = ROM128/ & !PRN;
ROM_A15 = DOS_en; -- сигнал RA15 = DOS/ & !PRN;
------------------------------------------------------------------------------------
-- Сигнал выбора ПЗУ
------------------------------------------------------------------------------------
ROM_SEL = Sel_A45 # C_MREQ;
CS_ROM = ROM_SEL;
------------------------------------------------------------------------------------
-- Сигнал чтения из ПЗУ
------------------------------------------------------------------------------------
RD_ROM = ROM_SEL # C_RD; -- сигнал RDROM/ = A45 # RD # MREQ
-----------------------------------------------------------------------------------
-- Сигнал записи в ПЗУ
------------------------------------------------------------------------------------
WR_ROM = VCC;
------------------------------------------------------------------------------------
-- Порты
------------------------------------------------------------------------------------
-- Сигнал управление портами
------------------------------------------------------------------------------------
IO_ENABLE = !C_M1 # C_IORQGE; --C_IORQ # C_IORQGE;
------------------------------------------------------------------------------------
-- Сигнал чтения из портов
------------------------------------------------------------------------------------
IO_RD = IO_ENABLE # C_RD;
------------------------------------------------------------------------------------
-- Сигнал записи в порты
------------------------------------------------------------------------------------
IO_WR = IO_ENABLE # C_WR;
------------------------------------------------------------------------------------
-- Порт xx1Fh - Кемпстон джойстик 00011111b
-----------------------------------------------------------------------------------
RD_1F = CA[7] # !(CA[3..0] == B"1111") # !DOS_En # IO_RD;
------------------------------------------------------------------------------------
-- Порт xxFEh = 11111110b
------------------------------------------------------------------------------------
WR_FE = !(CA[3..0] == B"1110") # IO_WR;
Border_Color_r[2..0].d = CD[2..0];
Border_Color_r[2..0].clk = WR_FE;
Border_Color_r[2..0].clrn = C_RESET;
Tape_r.d = CD[3];
Tape_r.clk = WR_FE;
Tape_r.clrn = C_RESET;
Beep_r.d = CD[4];
Beep_r.clk = WR_FE;
Beep_r.clrn = C_RESET;
------------------------------------------------------------------------------------
-- Выход магнитофона
------------------------------------------------------------------------------------
TAPE_OUT = Tape_r.q;
------------------------------------------------------------------------------------
-- Выход звука
------------------------------------------------------------------------------------
BEEP = Beep_r.q;
------------------------------------------------------------------------------------
-- Выход блокировки ПЗУ
------------------------------------------------------------------------------------
--C_BLK = GND;
------------------------------------------------------------------------------------
-- Селектор порта 7FFDh
-----------------------------------------------------------------------------------
Sel_7FFD = CA[15] # !CA[14] # !(CA[3..0] == B"1101") # IO_WR;
------------------------------------------------------------------------------------
-- Порт 7FFDh
-----------------------------------------------------------------------------------
WR_7FFD = Sel_7FFD # BLK_Port_r.q;
RAM0_Page_r[2..0].d = CD[2..0];
RAM0_Page_r[2..0].clk = WR_7FFD;
RAM0_Page_r[2..0].clrn = C_RESET;
SCR128_r.d = CD[3];
SCR128_r.clk = WR_7FFD;
SCR128_r.clrn = C_RESET;
ROM128_r.d = CD[4];
ROM128_r.clk = WR_7FFD;
ROM128_r.clrn = C_RESET;
BLK_Port_r.d = CD[5];
BLK_Port_r.clk = WR_7FFD;
BLK_Port_r.clrn = C_RESET;
------------------------------------------------------------------------------------
-- Порты BFFDh и FFFDh
------------------------------------------------------------------------------------
BC1 = CA[15] & CA[14] & (CA[3..0] == B"1101") & !IO_ENABLE;
BDIR = CA[15] & (CA[3..0] == B"1101") & !IO_WR;
------------------------------------------------------------------------------------
-- Частота AY-3-8912
------------------------------------------------------------------------------------
AYCLK = Sync_count[2].q; -- сигнал H1 = 1,75МГц
------------------------------------------------------------------------------------
-- Сигнал IODOS/
------------------------------------------------------------------------------------
-- C_IODOS = VCC;
------------------------------------------------------------------------------------
-- Доступ к контроллеру дисковода
------------------------------------------------------------------------------------
DOS_En = !DOS_r.q;
------------------------------------------------------------------------------------
-- TR-DOS контроллер
------------------------------------------------------------------------------------
-- Выбор окна ПЗУ
------------------------------------------------------------------------------------
Sel_code = C_M1 # C_MREQ;
Sel_3dxx = !(CA[15..8] == B"00111101") # !ROM128_r.q # Sel_code;
------------------------------------------------------------------------------------
-- Сигнал выбора контроллера NMI/
------------------------------------------------------------------------------------
NMI_r.d = C_MAGIC # !Sel_A45;
NMI_r.clk = Sel_code;
NMI_r.prn = Sel_3dxx;
------------------------------------------------------------------------------------
-- Сигнал NMI/
------------------------------------------------------------------------------------
C_NMI = NMI_r.q;
------------------------------------------------------------------------------------
-- Сигнал выбора контроллера DOS/
------------------------------------------------------------------------------------
DOS_r.clrn = C_RESET;
DOS_r.j = !(Sel_3dxx & NMI_r.q);
DOS_r.clk = !CLKZ;
DOS_r.k = !(Sel_code # !Sel_A45);
------------------------------------------------------------------------------------
-- Сигнал DOS/
------------------------------------------------------------------------------------
C_DOS = !DOS_r.q;
------------------------------------------------------------------------------------
-- Интерфейс клавиатуры
------------------------------------------------------------------------------------
-- Порт xxFEh - Клавиатура
------------------------------------------------------------------------------------
RDFE_Sel = !(CA[3..0] == B"1110") # IO_RD;
-----------------------------------------------------------------------------------
-- Счетчик
------------------------------------------------------------------------------------
KBD_save_en = KBD_count[0].q # KBD_count[1].q # KBD_count[2].q # !KBD_count[3].q;
KBD_count[].clk = !KBD_CLK;
KBD_count[].ena = KBD_save_en;
KBD_count[].clrn = !KBD_CS;
KBD_count[].d = KBD_count[].q + 1;
------------------------------------------------------------------------------------
-- Входной сдвигающий регистр
------------------------------------------------------------------------------------
KBD_shift_in[].clk = KBD_CLK;
IF KBD_count[3].q ==0 THEN
KBD_shift_in[].d = (KBD_shift_in[7-1..0].q,KBD_DI);
ELSE
KBD_shift_in[].d = KBD_shift_in[].q;
END IF;
------------------------------------------------------------------------------------
-- Регистры клавиатуры
------------------------------------------------------------------------------------
KBD_regA8[4..0].d = KBD_shift_in[7..3].q;
KBD_regA9[4..0].d = KBD_shift_in[7..3].q;
KBD_regA10[4..0].d = KBD_shift_in[7..3].q;
KBD_regA11[4..0].d = KBD_shift_in[7..3].q;
KBD_regA12[4..0].d = KBD_shift_in[7..3].q;
KBD_regA13[4..0].d = KBD_shift_in[7..3].q;
KBD_regA14[4..0].d = KBD_shift_in[7..3].q;
KBD_regA15[4..0].d = KBD_shift_in[7..3].q;
KBD_regA8[].clk = KBD_CLK;
KBD_regA8[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"000");
KBD_regA8[].prn = C_RESET;
KBD_regA9[].clk = KBD_CLK;
KBD_regA9[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"001");
KBD_regA9[].prn = C_RESET;
KBD_regA10[].clk = KBD_CLK;
KBD_regA10[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"010");
KBD_regA10[].prn = C_RESET;
KBD_regA11[].clk = KBD_CLK;
KBD_regA11[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"011");
KBD_regA11[].prn = C_RESET;
KBD_regA12[].clk = KBD_CLK;
KBD_regA12[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"100");
KBD_regA12[].prn = C_RESET;
KBD_regA13[].clk = KBD_CLK;
KBD_regA13[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"101");
KBD_regA13[].prn = C_RESET;
KBD_regA14[].clk = KBD_CLK;
KBD_regA14[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"110");
KBD_regA14[].prn = C_RESET;
KBD_regA15[].clk = KBD_CLK;
KBD_regA15[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"111");
KBD_regA15[].prn = C_RESET;
------------------------------------------------------------------------------------
-- Выходной буфер
------------------------------------------------------------------------------------
KBD_rddata[0].in = (CA8 # KBD_regA8[0].q) & (CA9 # KBD_regA9[0].q) & (CA10 # KBD_regA10[0].q) & (CA11 # KBD_regA11[0].q) & (CA12 # KBD_regA12[0].q) & (CA13 # KBD_regA13[0].q) & (CA14 # KBD_regA14[0].q) & (CA15 # KBD_regA15[0].q);
KBD_rddata[1].in = (CA8 # KBD_regA8[1].q) & (CA9 # KBD_regA9[1].q) & (CA10 # KBD_regA10[1].q) & (CA11 # KBD_regA11[1].q) & (CA12 # KBD_regA12[1].q) & (CA13 # KBD_regA13[1].q) & (CA14 # KBD_regA14[1].q) & (CA15 # KBD_regA15[1].q);
KBD_rddata[2].in = (CA8 # KBD_regA8[2].q) & (CA9 # KBD_regA9[2].q) & (CA10 # KBD_regA10[2].q) & (CA11 # KBD_regA11[2].q) & (CA12 # KBD_regA12[2].q) & (CA13 # KBD_regA13[2].q) & (CA14 # KBD_regA14[2].q) & (CA15 # KBD_regA15[2].q);
KBD_rddata[3].in = (CA8 # KBD_regA8[3].q) & (CA9 # KBD_regA9[3].q) & (CA10 # KBD_regA10[3].q) & (CA11 # KBD_regA11[3].q) & (CA12 # KBD_regA12[3].q) & (CA13 # KBD_regA13[3].q) & (CA14 # KBD_regA14[3].q) & (CA15 # KBD_regA15[3].q);
KBD_rddata[4].in = (CA8 # KBD_regA8[4].q) & (CA9 # KBD_regA9[4].q) & (CA10 # KBD_regA10[4].q) & (CA11 # KBD_regA11[4].q) & (CA12 # KBD_regA12[4].q) & (CA13 # KBD_regA13[4].q) & (CA14 # KBD_regA14[4].q) & (CA15 # KBD_regA15[4].q);
KBD_rddata[5].in = VCC;
KBD_rddata[6].in = TAPE_IN;
KBD_rddata[7].in = VCC;
KBD_rddata[].oe = !RDFE_Sel;
DATA_CPU[] = KBD_rddata[].out;
------------------------------------------------------------------------------------
-- Чтение из буферного регистра
------------------------------------------------------------------------------------
RD_MEMORY = !Sel_A45 # C_MREQ # C_RD;
REG_rddata[].in = Ram_buf[].q;
REG_rddata[].oe = !RD_MEMORY;
DATA_CPU[] = REG_rddata[].out;
CD[] = DATA_CPU[].out;
------------------------------------------------------------------------------------
-- Скандаблер на одну строку
------------------------------------------------------------------------------------
-- Счетчик адреса знакомест
------------------------------------------------------------------------------------
RH = HReset;
WHSync_count[].clk = CLK_14MHZ;
WHSync_count[].d = WHSync_count[].q+1;
WHSync_count[].clrn = !RH;
VHSync_count[].clk = !WHSync_count[5].q;
VHSync_count[].d = VHSync_count[].q+1;
VHSync_count[].clrn = VHReset & !RH;
SHSync_count[].clk = !WHSync_count[6].q;
SHSync_count[].d = SHSync_count[].q+1;
SHSync_count[].clrn = SHReset & !RH;
VHReset = !(VHSync_count[2..0].q ==B"111");
VHBlank = !(VHSync_count[2..0].q ==B"101");
SHReset = !(SHSync_count[2..0].q ==B"111");
------------------------------------------------------------------------------------
-- Строб строки знакомест
------------------------------------------------------------------------------------
MUX_data = !MUX_strobe.q;
MUX_strobe.clk = !(SHSync_count[2..0].q ==B"101");
MUX_strobe.d = MUX_data;
PA[9] = MUX_strobe.q $ VWR_strobe;
------------------------------------------------------------------------------------
-- Запись в буфер знакомест
------------------------------------------------------------------------------------
VWR_strobe = WHSync_count[0] & CLK_14MHZ;
VWR = !VWR_strobe;
------------------------------------------------------------------------------------
-- Aдреса знакомест
-----------------------------------------------------------------------------------
IF VWR_strobe == 0 THEN
PA[0] = WHSync_count[0].q; -- 7MГЦ
PA[1] = WHSync_count[1].q; -- 3,5МГЦ
PA[2] = WHSync_count[2].q; -- 1,75МГЦ
PA[3] = WHSync_count[3].q; -- 0,875МГЦ
PA[4] = WHSync_count[4].q; -- 0,875МГЦ
PA[5] = WHSync_count[5].q; -- 0,4375МГЦ
PA[6] = VHSync_count[0].q; -- 0,21875МГЦ
PA[7] = VHSync_count[1].q; -- 0,109375МГЦ
PA[8] = VHSync_count[2].q; -- 0,0546875МГЦ
ELSE
PA[0] = WHSync_count[1].q; -- 3,5МГЦ
PA[1] = WHSync_count[2].q; -- 1,75МГЦ
PA[2] = WHSync_count[3].q; -- 0,875МГЦ
PA[3] = WHSync_count[4].q; -- 0,875МГЦ
PA[4] = WHSync_count[5].q; -- 0,4375МГЦ
PA[5] = WHSync_count[6].q; -- 0,21875МГЦ
PA[6] = SHSync_count[0].q; -- 0,109375МГЦ
PA[7] = SHSync_count[1].q; -- 0,0546875МГЦ
PA[8] = SHSync_count[2].q; -- 0,0546875МГЦ
END IF;
PA[10] = GND;
PA[11] = GND;
PA[12] = GND;
PA[13] = VCC;
PA[14] = GND;
------------------------------------------------------------------------------------
-- Строб видеоданных
------------------------------------------------------------------------------------
VD[0] = VD_reg[0].q; -- Blue0
VD[1] = VD_reg[1].q; -- Blue1
VD[2] = VD_reg[2].q; -- Red0
VD[3] = VD_reg[3].q; -- Red1
VD[4] = GND; -- Red2
VD[5] = VD_reg[4].q; -- Green0
VD[6] = VD_reg[5].q; -- Green1
VD[7] = GND; -- Green2
VD_reg[].clk = CLK_14MHZ;
VD_reg[].d = PD[];
VD_reg[].clrn = VHBlank;
REG_wscan[].in = Reg_vid[].q;
REG_wscan[].oe = VWR_strobe;
PD[] = REG_wscan[].out;
END;
- - - Добавлено - - -
Сейчас посмотрел немного код Dizzy 3 в эмуляторе и похоже причина в IM 2. Тоесть когда стоит режим IM 1 то он замечательно работает, но как только переводит в IM 2 то похоже первое же прерывание приводит к краху всю систему