Русский клон ZX Spectrumа из прошлого
Moderator: Shaos
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
-
- God
- Posts: 1388
- Joined: 02 Jan 2006 02:28
- Location: Abakan
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
Что-то по этой маркировке гуглится только данный форум. А есть датащит?
PS Статическое ОЗУ отбирает слишком много ножек у CPLD. Надо найти способ подключения DRAM без нарушения таймингов либо придется чем-то жертвовать. Например функциями на ногах CPLD или установкой более ёмкого корпуса CPLD. Этот всего 100 ножек, следующий получается 144.
PS Статическое ОЗУ отбирает слишком много ножек у CPLD. Надо найти способ подключения DRAM без нарушения таймингов либо придется чем-то жертвовать. Например функциями на ногах CPLD или установкой более ёмкого корпуса CPLD. Этот всего 100 ножек, следующий получается 144.
-
- God
- Posts: 1388
- Joined: 02 Jan 2006 02:28
- Location: Abakan
-
- Doomed
- Posts: 459
- Joined: 23 Nov 2007 15:53
- Location: Saint Petersburg, Russia
jdigreze личку глянь
"Очень трудно найти чёрную кошку в тёмной комнате... особенно, если её там нет.", "Forever!". 
zx.clan.su - Soviet Union ZX Spectrum Community - форум посвящённый развитию Спека.

zx.clan.su - Soviet Union ZX Spectrum Community - форум посвящённый развитию Спека.
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
Сегодня мне повезло! Разгребая закрома я обнаружил-таки свою заначку из 8ми микросхем LH21256-12. Это аналоги РУ7. Так что откачу проект до использования этой памяти. Использование SRAM конечно удобнее и логичнее, но она слишком много съедает ног у CPLD. Не остается на остальные устройства. Как переделаю печатку и подправлю схему внутри CPLD сразу отпишу о результатах.
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
В общем решил все-же отказаться от DRAM. Проблема регенерации идет в ущерб оригинальным таймингам. Поэтому, остаемся на SRAM. Однако, чтобы сэкономить ноги в CPLD адреса придется мультиплексировать. А сигналы управления уже готовы - это RAS/CAS. Как только перепаяю макетку согласно новому плану - отпишусь.
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
Вернулся из отпуска, вспомнил про спектрум. Подпаял клавиатуру:

Дополнил портом ввода и вывода (пока только управление бордюром). USB тюнер куда-то делся, а встроенный показывает ужасно:



Однако, работает. Осталось только привести в порядок видеовыход, магнитофонный интерфейс. После этого можно начать пересматривать текущий вариант проекта и попробовать переписать его на верилог. Я его еще толком не изучал, так несколько книжек почитал. Надеюсь, получится.

Дополнил портом ввода и вывода (пока только управление бордюром). USB тюнер куда-то делся, а встроенный показывает ужасно:



Однако, работает. Осталось только привести в порядок видеовыход, магнитофонный интерфейс. После этого можно начать пересматривать текущий вариант проекта и попробовать переписать его на верилог. Я его еще толком не изучал, так несколько книжек почитал. Надеюсь, получится.
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
В общем пока вот так получилось:

Выгрузка:


Кодер PAL говно, ЧБ изображение с RGBI просто конфетка. Либо внешний аналоговый кодер цеплять, либо нормальный писать, который может и не влезть. Схему уже переложил на Verilog, наверняка накосячил прилично. Нужно нарисовать схему по текущему варианту. А тут можно загружать файлы или надо пользоваться внешними хранилищами? Я бы проект приложил, пусть знающие люди посмотрят.

Выгрузка:


Кодер PAL говно, ЧБ изображение с RGBI просто конфетка. Либо внешний аналоговый кодер цеплять, либо нормальный писать, который может и не влезть. Схему уже переложил на Verilog, наверняка накосячил прилично. Нужно нарисовать схему по текущему варианту. А тут можно загружать файлы или надо пользоваться внешними хранилищами? Я бы проект приложил, пусть знающие люди посмотрят.
-
- God
- Posts: 1388
- Joined: 02 Jan 2006 02:28
- Location: Abakan
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
Это кодер. В статике любой цвет бордюра достаточно насыщен и основное поле от этого не страдает. Именно для этого и выставлена первая картинка - там простая программка на бейсике, картинка статична. А вот в динамике мало того кодер врет да еще и тюнер деинтерлейсит. Картинка с пилоттоном там два цвета накладываются деинтерлейсом. На телевизоре вроде получше. Сейчас еще раз окину код взглядом и попробую как-нибудь прикрепить.
-
- Fanat
- Posts: 79
- Joined: 10 Feb 2014 03:37
В общем, получилось как-то так:
Специалистам просьба глянуть и указать на явные ошибки.
Code: Select all
// ULA клона ZX Spectrum Ленинград
module LeninULA(
// Входы общие
input MClk, // Тактовая частота 14.31818 (компьютерный кварц)
// Входы Z80
input [15:0]A, // Шина адреса
input M1, // Сигнал Machine Cycle 1
input RFSH, // Сигнал Refresh
input MREQ, // Сигнал Memory Request
input IORQ, // Сигнал Input-Output Request
input RD, // Сигнал Read Strobe
input WR, // Сигнал Write Strobe
// Входы периферии
input [4:0]KI, // Вход матрицы клавиатуры
input TAPEIN, // Вход магнитофона
// Выходы периферии
output reg SOUND, // Выход звука
output reg TAPEOUT, // Выход магнитофона
// Выходы Z80
output reg CLK, // Выход тактовой частоты
output reg WAIT, // Выход Wait
output reg INT, // Выход Interrupt
output reg NMI, // Выход NonMaskable Interrupt
output reg BUSR, // Выход Bus Request
output reg RES, // Выход Reset
// Выходы памяти
output reg [7:0]MA, // Выход мультиплексированной шины адреса ОЗУ
output reg RWE, // Выход строба записи ОЗУ
output reg ROE, // Выход строба чтения ОЗУ
output reg ROM, // Выход обращения к ПЗУ
// Выход видео
output SYNC, // Выход синхронизации
output reg R, // Выход сигнала R
output reg G, // Выход сигнала G
output reg B, // Выход сигнала B
output reg I, // Выход сигнала I
output ODD, // Выход чет/нечет
output reg BURST, // Снхровспышка цветности
// Двунаправленные шины
inout [7:0]D, // Шина данных Z80
inout [7:0]MD // Шина данных ОЗУ
);
assign SYNC = !SS & !KS;
assign ODD = VC[0];
assign D[7:0] = (CSRAM & !RD) ? LATCH[7:0] :
(!IORQ & !RD) ? (A[0]) ? 8'h00 : {1'h0,TAPEIN,1'h0,KI[4:0]} : 8'hzz;
assign MD[7:0] = (!RWE) ? D[7:0] : 8'hzz;
// Основной арбитр
reg [3:0]STATE; // Состояние арбитра
reg [7:0]LATCH; // Защелка входных данных Z80
reg [7:0]ATTR; // Регистр атрибутов
reg [11:0]VID; // Регистр видеосигнала
reg [7:0]RA; // Адресный регистр
reg [2:0]BORDER; // Регистр бордюра
reg RAMEDGE; // Перепад обращения к ОЗУ
reg DLATCH; // Запрос на запись данных
reg WINDOW; // Окно отображения
wire CSRAM = !MREQ & !RD & (A[14] | A[15]); // Выборка ОЗУ
wire WERAM = !MREQ & RD & RFSH; // Запись в ОЗУ
//
always @(posedge MClk)
begin
// RAS / CLK для Z80 с небольшой задержкой
CLK <= STATE[1];
// CAS / ROE/RWE
if (STATE[2])
begin
// Обращение видеопроцессора
ROE <= !(STATE[1] ^ STATE[0]);
end
else
begin
// Обращение Z80
ROE <= !(!MREQ & !(RD & RFSH) & (A[14] | A[15]) & (STATE[1] ^ STATE[0]));
// CAS / RWE
RWE <= !(WERAM & (A[14] | A[15]) & !STATE[1] & STATE[0]);
end
// Ожидание и выборка ПЗУ
ROM <= MREQ | RD | A[14] | A[15];
if (!STATE[2] & !STATE[1] & STATE[0])
begin
// Загрузка латча, снятие ожидания
DLATCH <= 1'b1; WAIT <= 1'b1;
end
else
begin
DLATCH <= 1'b0;
end;
RAMEDGE <= CSRAM;
if (!RAMEDGE & CSRAM & !M1) WAIT <= 1'b0;
// Видео ???
if (!STATE[3] & STATE[2] & STATE[1])
begin
// Загрузка новых данных
if (!STATE[0]) VID[11:0] <= {VID[10:7],MD[7:0]};
end
else
begin
// Сдвиг видеорегистра
if (!STATE[0]) VID[11:0] <= {VID[10:0],1'b1};
end;
// Атрибуты
if (STATE[3] & STATE[2] & STATE[1] & !STATE[0])
begin
WINDOW <= !HC[5] & !(VC[8] | (VC[7] & VC[6]));
ATTR[7:0] <= MD[7:0];
end
// Видеовыход
if (WINDOW)
begin
// Вывод видео
I <= ATTR[6];
if (VID[11] ^ (ATTR[7] & FLASH[4]))
begin
// INK
B <= ATTR[0]; R <= ATTR[1]; G <= ATTR[2];
end
else
begin
// PAPER
B <= ATTR[3]; R <= ATTR[4]; G <= ATTR[5];
end
end
else
begin
if (!SG & !KG)
begin
// Бордюр
B <= BORDER[0]; R <= BORDER[1]; G <= BORDER[2]; I <= 1'b0;
end
else
begin
// Гашение
B <= 1'b0; R <= 1'b0; G <= 1'b0; I <= 1'b0;
end
end
// Адресный мультплексор
case (STATE[3:1])
3'h0 : RA[7:0] <= A[7:0];
3'h1 : RA[7:0] <= {3'h2,VC[7:6],VC[2:0]};
3'h2 : RA[7:0] <= {VC[5:3],HC[4:0]};
3'h3 : RA[7:0] <= A[15:8];
3'h4 : RA[7:0] <= A[7:0];
3'h5 : RA[7:0] <= {6'h16,VC[7:6]};
3'h6 : RA[7:0] <= {VC[5:3],HC[4:0]};
3'h7 : RA[7:0] <= A[15:8];
endcase
// Цветовая вспышка
if (HC[5] & !HC[4] & HC[3] & HC[2] & !HC[1] & HC[0] & STATE[3]) BURST <= 1'b1;
if (HC[5] & !HC[4] & HC[3] & HC[2] & HC[1] & HC[0] & STATE[3]) BURST <= 1'b0;
// Строчное гашение
if (HC[5] & !HC[4] & !HC[3] & HC[2] & HC[1] & HC[0]) SG <= 1'b1;
if (HC[5] & HC[4] & !HC[3] & !HC[2] & !HC[1] & !HC[0]) SG <= 1'b0;
// Гоняем состояние по кругу
STATE[3:0] <= STATE[3:0] + 4'h1;
// Загрузка в порт
if (!IORQ & !WR) {SOUND,TAPEOUT,BORDER[2:0]} <= D[4:0];
// Заглушки
NMI <= 1'b1;
BUSR <= 1'b1;
RES <= 1'b1;
end
always @(negedge MClk)
begin
MA[7:0] <= RA[7:0];
if (DLATCH) LATCH[7:0] <= MD[7:0];
end
// Строчный счетчик
reg [5:0]HC; // Строчный счетчик
reg SS; // Строчная синхронизация
reg SG; // Строчное гашение
reg INTEDGE; // Перепад прерывания
always @(negedge STATE[3])
begin
// Счет
if (HC[5:0] == 6'h38)
begin
// Сброс счетчика
HC[5:0] <= 6'h00;
end
else
begin
// Счет
HC[5:0] <= HC[5:0] + 6'h01;
end;
SS <= HC[5] & !HC[4] & HC[3] & !HC[2];
if (!INTEDGE & !VC[8] & VC[7] & VC[6])
begin
INT <= 1'b0;
end
else
begin
INT <= 1'b1;
end
INTEDGE <= !VC[8] & VC[7] & VC[6];
end
// Кадровый счетчик
reg [8:0]VC; // Кадровый счетчик
reg KS; // Кадровая синхронизация
reg KG; // Кадровое гашение
always @(negedge SS)
begin
// Счет
if (VC[8:0] == 9'h137)
begin
VC[8:0] <= 9'h00;
end
else
begin
VC[8:0] <= VC[8:0] + 9'h01;
end
KS <= !VC[8] & VC[7] & VC[6] & VC[5] & VC[4] & VC[3] & !VC[2];
KG <= (!VC[8] & VC[7] & VC[6] & VC[5] & VC[4]) | (VC[8] & !VC[7] & !VC[6] & !VC[5] & !VC[4]);
end
// Мигалка
reg [4:0]FLASH;
always @(posedge KS)
begin
FLASH[4:0] <= FLASH[4:0] + 5'h01;
end
// Конец модуля
endmodule
-
- God
- Posts: 1388
- Joined: 02 Jan 2006 02:28
- Location: Abakan