903 lines
39 KiB
Plaintext
903 lines
39 KiB
Plaintext
----------------------------------------------------------------------------------------------------------------------------
|
||
-- Описание: Прошивка микросхемы CPLD DD1 (модуль EPM3256AQC208_IGP1 Вариант 2)
|
||
-- Проект: ZXM-Jasper
|
||
-- Автор: Тарасов М.Н. (Mick)
|
||
-- Тип CPLD: EPM3256AQC208
|
||
-- Версия: v1.00 - 01 декабря 2017
|
||
----------------------------------------------------------------------------------------------------------------------------
|
||
TITLE "ZXM-Jasper System Array Logic";
|
||
|
||
FUNCTION 2mux1 (a, b, sel) RETURNS (y);
|
||
|
||
SUBDESIGN MODULE_CPLD
|
||
(
|
||
-- Входная тактовая частота CLK
|
||
CLK_14MHZ : INPUT;
|
||
|
||
-- Сигналы управления RAM памятью
|
||
MA[18..0] : OUTPUT;
|
||
MD[7..0] : BIDIR;
|
||
WR_RAM : OUTPUT;
|
||
CS_RAML : OUTPUT;
|
||
CS_RAMH : OUTPUT;
|
||
|
||
-- Выходные сигналы видео формирователя
|
||
VD[7..0] : OUTPUT;
|
||
HS : OUTPUT;
|
||
VS : OUTPUT;
|
||
GI : OUTPUT;
|
||
|
||
-- Сигналы управления ROM памятью
|
||
ROM_A14 : OUTPUT;
|
||
ROM_A15 : OUTPUT;
|
||
ROM_A16 : OUTPUT;
|
||
ROM_A17 : OUTPUT;
|
||
ROM_A18 : 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_IORQGE : INPUT;
|
||
C_INT : OUTPUT;
|
||
C_NMI : OUTPUT;
|
||
|
||
C_BLK : INPUT; -- просто декларируем (не используется)
|
||
C_BUSRQ : INPUT; -- просто декларируем (не используется)
|
||
C_WAIT : INPUT; -- просто декларируем (не используется)
|
||
C_IODOS : INPUT; -- просто декларируем (не используется)
|
||
|
||
C_DOS : OUTPUT;
|
||
|
||
-- Сигналы взаимодействия c AVR
|
||
C_MAGIC : INPUT;
|
||
C_PNT : INPUT;
|
||
--C_TURBO : INPUT;
|
||
|
||
-- Сигналы AY-3-8912
|
||
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[7..0] : BIDIR; -- данные
|
||
|
||
-- Сигналы клавиатуры
|
||
KBD_CS : INPUT;
|
||
KBD_CLK : INPUT;
|
||
KBD_DI : INPUT
|
||
)
|
||
VARIABLE
|
||
|
||
Sync_count[2..0] : DFF; -- 3-х разрядный счетчик, сигналы TI, H0, H1
|
||
CLKZ : NODE; -- частота процессора
|
||
H0M : NODE; -- частота селектора памяти
|
||
H1M : NODE; -- частота селектора памяти
|
||
VCLK : NODE; -- опорная частота видеосчетчиков
|
||
|
||
HSync_count[6..0] : DFF; -- 7-и разрядный счетчик строчной разверкти, сигналы H2, H3..H8
|
||
HReset : NODE; -- сброс счетчиков строчной развертки
|
||
HBlank : NODE; -- сигнал гашения видеосигнала строчный
|
||
HBlank1 : NODE; -- сигнал гашения видеосигнала строчный
|
||
HBlank2 : NODE; -- сигнал гашения видеосигнала строчный
|
||
HBlank3 : DFF; -- сигнал гашения видеосигнала строчный
|
||
HBorder : NODE; -- сигнал строчного бордера
|
||
HSync : DFF; -- строчный синхроимпульс
|
||
HSync1 : DFF; -- синхроимпульс счета кадровых счетчиков
|
||
|
||
VSync_count[8..0] : DFF; -- 9-и разрядный счетчик кадровый развертки, сигналы V0..V8
|
||
VReset : NODE; --сброс счетчиков кадровой развертки
|
||
VSync : DFF; -- кадровый синхроимпульс
|
||
VBorder : NODE; -- сигнал кадрового бордера
|
||
|
||
Border_sync : DFF; -- строб бордера
|
||
Int_sync : DFF; -- строб прерывания
|
||
Int_count[3..0] : DFF; -- 4-и разрядный счетчик длительности прерывания
|
||
Flash_count[4..0] : DFF; -- 5-и разрядный счетчик мерцания, сигнал FLASH
|
||
|
||
REG_rddata[7..0] : TRI; -- буфер чтения памяти
|
||
DATA_CPU[7..0] : TRI_STATE_NODE;
|
||
|
||
-- Сигналы управления памятью
|
||
WR_RAM : LCELL;
|
||
WR_Buf : LCELL; -- запись в буферный регистр
|
||
VA[4..0] : NODE; -- адрес видео памяти
|
||
RA[5..0] : NODE; -- адрес видео памяти
|
||
Sel_A45 : NODE; -- доступ к ОЗУ
|
||
Ram_sel : DFF;
|
||
Ram_write_r : DFFE; -- запись в ОЗУ
|
||
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; -- запись в порты
|
||
|
||
-- TR-DOS контроллер
|
||
Sel_code : NODE; -- выбор ПЗУ TRDOS
|
||
Sel_3dxx : NODE; -- выбор ПЗУ TRDOS
|
||
DOS_r : JKFF; -- выбор ПЗУ TRDOS
|
||
NMI_r : DFF; -- выбор ПЗУ TRDOS
|
||
DOS_En : 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[4..0] : DFF; -- основные страницы 128кб + доролнительные страницы выше 128кб (общий объём 1024)
|
||
SCR128_r : DFF; --экран в 4000h или C000h (3 - бит)
|
||
ROM128_r : DFF; -- 128 ПЗУ (4 - бит)
|
||
BLK_Port_r : DFF; -- блокировка записи в порт (5 - бит)
|
||
|
||
-- Скандаблер
|
||
VWR : LCELL;
|
||
VHReset : NODE;
|
||
VHBlank : NODE;
|
||
SHReset : NODE;
|
||
VWR_strobe : LCELL; -- запись в буфер
|
||
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[7..0] : TRI;
|
||
RH : NODE;
|
||
|
||
|
||
-- интерфейс клавиатуры
|
||
RDFE_Sel : LCELL; -- выбор клавиатуры
|
||
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 31250 Hz
|
||
-- Field frequency 48 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 верхний бордер
|
||
-- =
|
||
-- 320 сброс счетчиков кадровой развертки
|
||
------------------------------------------------------------------------------------
|
||
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");
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал строчной развертки
|
||
------------------------------------------------------------------------------------
|
||
HS = HSync.q;
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал кадровой развертки
|
||
------------------------------------------------------------------------------------
|
||
VS = VSync.q;
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал гашения (разрешает работу выходному регистру DD7 - КР1533ИР27)
|
||
------------------------------------------------------------------------------------
|
||
GI = GND;
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Счетчики мерцания
|
||
------------------------------------------------------------------------------------
|
||
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");
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал прерывания
|
||
------------------------------------------------------------------------------------
|
||
C_INT = Int_sync.q;
|
||
|
||
-----------------------------------------------------------------------------------
|
||
-- Видеоформирователь
|
||
------------------------------------------------------------------------------------
|
||
-- Стробирующие сигналы захвата информации
|
||
------------------------------------------------------------------------------------
|
||
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
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал формирование частоты процессора
|
||
-- Примечание: процессор на частоте 3,5МГц(NORMAL)
|
||
------------------------------------------------------------------------------------
|
||
H0M = Sync_count[1].q; -- H0
|
||
H1M = Sync_count[2].q; -- H1
|
||
|
||
CLKZ = !H0M;
|
||
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;
|
||
-- Ram_write_r.prn = VCC;
|
||
|
||
Ram_write_r.ena = !CLKZ; --!Clk_reg[0].q; --память работает в турбо режиме 7МГц
|
||
Ram_write_r.clk = !CLK_14MHZ;
|
||
------------------------------------------------------------------------------------
|
||
-- Запись в память
|
||
------------------------------------------------------------------------------------
|
||
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];
|
||
RA[3] = GND;
|
||
RA[4] = GND;
|
||
RA[5] = GND;
|
||
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
|
||
|
||
|
||
RA[3] = RAM0_PAGE_r[3].q; -- сигнал Page3 256
|
||
RA[4] = RAM0_PAGE_r[4].q; -- сигнал Page4 512
|
||
RA[5] = BLK_Port_r.q; -- сигнал Page5 1024 (MA19*)
|
||
END IF;
|
||
|
||
-- RA[3] = GND;
|
||
-- RA[4] = GND;
|
||
-- RA[5] = GND;
|
||
------------------------------------------------------------------------------------
|
||
-- Формирование адресов и выбор микросхемы памяти
|
||
------------------------------------------------------------------------------------
|
||
IF H1M ==0 THEN
|
||
MA[13..0] = CA[13..0];
|
||
MA[18..14] = RA[4..0];
|
||
RAM_sel.d = RA[5];
|
||
|
||
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
|
||
|
||
MA[17] = GND;
|
||
MA[18] = GND;
|
||
RAM_sel.d = GND;
|
||
|
||
END IF;
|
||
|
||
Ram_sel.clk = !CLK_14MHZ;
|
||
Ram_sel.clrn = C_RESET;
|
||
|
||
CS_RAML = Ram_sel.q; --0
|
||
CS_RAMH = !Ram_sel.q; --MA[19]* --1
|
||
|
||
|
||
-- CS_RAML = BLK_Port_r.q; --0
|
||
-- CS_RAMH = !BLK_Port_r.q; --MA[19]* --1
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Управление памятью ROM
|
||
------------------------------------------------------------------------------------
|
||
-- Формирование управляющих сигналов ROM памяти
|
||
------------------------------------------------------------------------------------
|
||
|
||
-- A14=0 A15=0 MONITOR
|
||
-- A14=1 A15=0 DOS
|
||
-- A14=0 A15=1 128
|
||
-- A14=1 A15=1 48
|
||
|
||
ROM_A14 = ROM128_r.q;-- # !DOS_En; -- сигнал RA14 = ROM128/ & !PRN;
|
||
ROM_A15 = !DOS_r.q; -- сигнал RA15 = DOS/ & !PRN;
|
||
|
||
ROM_A16 = GND;
|
||
ROM_A17 = GND;
|
||
ROM_A18 = GND;
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал выбора ПЗУ
|
||
------------------------------------------------------------------------------------
|
||
ROM_SEL = Sel_A45 # C_MREQ;
|
||
|
||
CS_ROM = GND;
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал чтения из ПЗУ
|
||
------------------------------------------------------------------------------------
|
||
RD_ROM = ROM_SEL # C_RD; -- сигнал RDROM/ = A45 # RD # MREQ
|
||
-----------------------------------------------------------------------------------
|
||
-- Сигнал записи в ПЗУ
|
||
------------------------------------------------------------------------------------
|
||
WR_ROM = VCC;
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Порты
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал управление портами
|
||
------------------------------------------------------------------------------------
|
||
IO_ENABLE = !C_M1 # 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;
|
||
------------------------------------------------------------------------------------
|
||
-- Селектор порта 7FFDh
|
||
-----------------------------------------------------------------------------------
|
||
Sel_7FFD = CA[15] # !(CA[7..0] == B"11111101") # IO_WR;
|
||
------------------------------------------------------------------------------------
|
||
-- Порт 7FFDh
|
||
-----------------------------------------------------------------------------------
|
||
WR_7FFD = Sel_7FFD # (BLK_Port_r.q & C_PNT);
|
||
|
||
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;
|
||
|
||
|
||
-- C_PNT
|
||
--
|
||
-- BLK_Port_r.d = CD[5];
|
||
-- BLK_Port_r.clk = WR_7FFD;
|
||
-- BLK_Port_r.clrn = C_RESET;
|
||
|
||
IF C_PNT ==0 THEN -- (mem=1024)
|
||
|
||
BLK_Port_r.d = CD[5]; -- сигнал Page5 1024
|
||
BLK_Port_r.clk = WR_7FFD;
|
||
BLK_Port_r.clrn = C_RESET;
|
||
|
||
|
||
RAM0_Page_r[4..3].d = CD[7..6]; -- сигнал Page3/4 256/512
|
||
RAM0_Page_r[4..3].clk = WR_7FFD;
|
||
RAM0_Page_r[4..3].clrn = C_RESET;
|
||
|
||
ELSE -- (mem = 128)
|
||
BLK_Port_r.d = CD[5];
|
||
BLK_Port_r.clk = WR_7FFD;
|
||
BLK_Port_r.clrn = C_RESET;
|
||
|
||
RAM0_Page_r[4..3].d = GND;
|
||
RAM0_Page_r[4..3].clk = WR_7FFD;
|
||
RAM0_Page_r[4..3].clrn = C_RESET;
|
||
END IF;
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Порты BFFDh и FFFDh
|
||
------------------------------------------------------------------------------------
|
||
BC1 = CA[15] & CA[14] & (CA[7..0] == B"11111101") & !IO_ENABLE;
|
||
BDIR = CA[15] & (CA[7..0] == B"11111101") & !IO_WR;
|
||
------------------------------------------------------------------------------------
|
||
-- Частота AY-3-8912
|
||
------------------------------------------------------------------------------------
|
||
AYCLK = Sync_count[2].q; -- сигнал H1 = 1,75МГц
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Доступ к контроллеру дисковода
|
||
------------------------------------------------------------------------------------
|
||
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 & C_RESET;
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал NMI/
|
||
------------------------------------------------------------------------------------
|
||
C_NMI = NMI_r.q;
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал выбора контроллера DOS/
|
||
------------------------------------------------------------------------------------
|
||
|
||
---------------------------СИГНАЛ DOS НА ТМ7----------------------------------------
|
||
DOS_r.clrn = C_RESET;
|
||
DOS_r.j = !(Sel_3dxx & NMI_r.q);
|
||
DOS_r.clk = !CLK_14MHZ;
|
||
DOS_r.k = !(Sel_code # !Sel_A45);
|
||
|
||
---------------------------СИГНАЛ DOS НА ТМ2----------------------------------------
|
||
--DOS_r.prn = !(Sel_code # !Sel_A45) & C_RESET;
|
||
--DOS_r.clrn = (Sel_3dxx # Sel_code) & NMI_r.q;
|
||
--DOS_r.clk = vcc;
|
||
--DOS_r.d = vcc;
|
||
------------------------------------------------------------------------------------
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Сигнал DOS/
|
||
------------------------------------------------------------------------------------
|
||
C_DOS = !DOS_r.q; -- 0 = Активный ДОС
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Интерфейс клавиатуры
|
||
------------------------------------------------------------------------------------
|
||
-- Порт xxFEh - Клавиатура
|
||
------------------------------------------------------------------------------------
|
||
RDFE_Sel = !(CA[7..0] == B"11111110") # 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;
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Скандаблер на одну строку
|
||
------------------------------------------------------------------------------------
|
||
-- Счетчик адреса знакомест
|
||
------------------------------------------------------------------------------------
|
||
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_strobe : LCELL; -- запись в буфер
|
||
|
||
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] = VCC;
|
||
PA[11] = VCC;
|
||
PA[12] = VCC;
|
||
PA[13] = VCC;
|
||
PA[14] = VCC;
|
||
------------------------------------------------------------------------------------
|
||
-- Строб видеоданных
|
||
------------------------------------------------------------------------------------
|
||
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[5..0].d = PD[5..0];
|
||
VD_reg[].clrn = VHBlank;
|
||
|
||
REG_wscan[5..0].in = Reg_vid[5..0].q;
|
||
REG_wscan[7..6] = GND;
|
||
REG_wscan[].oe = VWR_strobe & CLK_14MHZ; -- good tv 12
|
||
|
||
PD[] = REG_wscan[].out;
|
||
|
||
------------------------------------------------------------------------------------
|
||
-- Взаимодействие с ШД процессора
|
||
------------------------------------------------------------------------------------
|
||
|
||
CD[] = DATA_CPU[];
|
||
--=====================================================================================
|
||
END;
|
||
|