Автор: SuperMax 16.4.2021, 11:52
Модель управления памятью в AZ V2 с поддержкой эмуляции БК11М на БК10
Правки от 2023-04-13
Концепция:
маппер V2 - это чисто маппер AZ без костылей и _все_ запросы к мапперам 177716(БК11М) или 177130(СМК) транслируются в маппер AZ который является единым устройством управления памятью
это сделано для кардинального расширения возможностей БКшек, а именно для отключения 037й
и как следствие - возможности работы полного маппера AZ. Это означает что на любой адрес в адресном пространстве БК10/БК11М можно подставить любую страницу памяти!
адресное пространство расширенной памяти разбито на 4 сегмента:
Код
АДРЕСНОЕ ПРОСТРАНСТВО ПАМЯТИ В AZ
╔═══════════════════════════════════════════════════ ..... ════════╗
║ АДРЕСНОЕ ПРОСТРАНСТВО ПАМЯТИ В AZ ║
╚═══════════════════════════════════════════════════ ..... ════════╝
0 128kB 256kB 512kB 1024kB 32MB
│ │ │ │ │
└───────┤ ├───────┴────────┘
RAM │ │ ROMs SMK
Shadow │ │
│ │
└─SYSTEM─┘
0-128кБ (страницы
0-37) это
память для организации "теневой" или эмулируемой памяти БК11М
первые 128кБ являются полной копией оперативки БК11М - или эмулируемой в БК10
из этой памяти идет отображение legacy видео режимов
что такое теневая (shadow) память:суть в том, что все обращения к оперативной памяти есть на шине МПИ
запросы это конкретный цикл обмена по шине - те выставление SYNC+адрес, подтверждение RPLY
и затем DOUT и DIN те нормальный режим работы.
теневая память это память куда пишется (те производится выполнение цикла SYNC+DOUT) с получением адреса и данных которые пишутся в память. те технически это копия по-записи реальной памяти в БК.
так как у нас есть копия - то получается есть техническая возможность отобразить на экран любую страницу памяти БК11М
обращаю внимание на то, что физический адрес - словный
режим работы этой памяти устанавливается в регистре
177346128-256кБ (страницы
40-77)
это полноценная R/W память с которой всегда идет RPLY
но эта память служебная и используется для работы AZ контроллера
256-512кБ (страницы
100-177) это
read-only память, она не доступна на запись со стороны БКшки
эта память для эмуляции различных ПЗУ, содержимое которых может быть загружено только средствами AZ
512-1024кБ (страницы
200-377) для эмуляции SMK-512
Начиная с
1МБ (страницы
400-17777) вся оперативная память - полноценная
R/W память без ограничений, а именно ее подключение всегда дает RPLY на чтение и на запись если не установлен режим r/o на данной странице в регистре 177342
маппер памяти AZтехнически адрес в системе 24bit-а (адрес слова 16bit)
для маппера памяти используется старшая часть адреса, и получается дискретность привязки памяти к окну - 4кБ
есть 16 регистров (
177300-177336 R/W) куда пишется 13bit адрес начала (11 бит добавляется от адреса с шины и получается 24bit адрес слова)
старшие 3 бита в резеве и маппер предусматривает расширение до 256МБ.
Код
ПРИНЦИП ФОРМИРОВАНИЯ ПОЛНОГО 24bit АДРЕСА 16bit слова
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│23│22│21│20│19│18│17│16│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │ │ │
└────────────────────────────────────┘ └──────────────────────────────┘
АДРЕС В РЕГИСТРЕ ОКНА 13bit АДРЕС С ШИНЫ МЛАДШИЕ 11bit
Адресное пространство разбито на 16 окон
для облегчения восприятия я пронумерую их с 0 до 15
┌────────┬────────────┬────────────┬────────────┬────────────┬────────────┬────────────┬────────────┬─
│0..7777 │10000..17777│20000..27777│30000..37777│40000..47777│50000..57777│60000..67777│70000..77777│
└────────┴────────────┴────────────┴────────────┴────────────┴────────────┴────────────┴────────────┴─
0 окно 1 окно 2 окно 3 окно 4 окно 5 окно 6 окно 7 окно
177300 177302 177304 177306 177310 177312 177314 177316
──┬─────────────┬──────────────┬──────────────┬──────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
│100000-107777│110000..117777│120000..127777│130000..137777│140000..147777│150000..157777│160000..167777│170000..177000│
──┴─────────────┴──────────────┴──────────────┴──────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
8 окно 9 окно 10 окно 11 окно 12 окно 13 окно 14 окно 15 окно
177320 177322 177324 177326 177330 177332 177334 177336
Регистр управления активацией окно - маски окон
АДРЕС = 177340 R/W
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
пример: для подключения оперативки в окно №14 - 160000-167777
надо сделать следующее:
177334 <- 400 (это указатель на первый мегабайт)
177340 <- 40000 (это разрешение этого окна - 14 бит)
177342 <- сброс бита 14 тк мы хотим оперативку а не ПЗУ
Регистр управления r/o на окно
АДРЕС = 177342 R/W
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
пример: для подключения оперативки в режиме ПЗУ
в окно №14 - 160000-167777 надо сделать следующее:
177334 <- 400 (это указатель на первый мегабайт)
177340 <- 40000 (это разрешение этого окна - 14 бит)
177342 <- 40000 (это установка r/o тк мы хотим ПЗУ)
Регистр управления shadow окон - маски окон
АДРЕС = 177344 R/W
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
shadow это режим копирования всех операций записи в зеркальную память - см
АДРЕСНОЕ ПРОСТРАНСТВО ПАМЯТИ В AZ
╔═══════════════════════════════════════════════════ ..... ════════╗
║ АДРЕСНОЕ ПРОСТРАНСТВО ПАМЯТИ В AZ ║
╚═══════════════════════════════════════════════════ ..... ════════╝
0 128kB 256kB 512kB 1024kB 32MB
│ │
└───────┘
SHADOW RAM
Это нужно для работы на БК11М и формирования изображения на VGA экране
shadow страницы устанавливаются автоматически при работе с маппером БК11М
для управления маппером предусмотрен регистр маски окон -
177340 R/W
младший бит соответствует младшему окну (те с 0 до 7777)
пример: для подключения оперативки в окно 160000-167777 надо сделать следующее:
177334 <- 400 (это указатель на первый мегабайт)
177340 <- 40000 (это разрешение этого окна)
для управления r/o на выбранном окне предусмотрен регистр-маска
177342соответственно для установки режима только чтения надо установить соответствующий бит на окне
к примеру
177334 <- 400 (это указатель на первый мегабайт)
177340 <- 40000 (это разрешение этого окна)
177342 <- 40000 это запрет записи в это (160000-167777) окно
разбивка на окна соответствует размеру в SMK - те 4кБ начиная со 100000(8)
обращаю внимание на адресацию, те свойства r/o w/o привязаны к 24bit адресу слова (!)
также есть регистр управления который осуществляет включение/выключение окон по маске (177342) + для общего управления и совместимостью с SMK
регистр управления shadow режимом 177344 R/Wэто тоже битовая маска окон, и младший бит соответствует младшему окну
назначение регистра - управление работой shadow-режима для БК11М
как уже было сказано - маппер V2 это полный маппер
и соответственно в режиме БК11М - первые 128кБ это тень памяти БК11М
для этого в регистры 177330 и далее прописываются соответствия страниц памяти в которые будет "откидываться" вся запись в память БК11М и будет обеспечиваться ее копия в памяти AZ.
к примеру
177300 <=13'o030; // 000000-007777
177302 <=13'o031; // 010000-017777
177304 <=13'o032; // 020000-027777
177306 <=13'o033; // 030000-037777
те это нулевая страница в понятии БК11М
и соответственно в 177344 устанавливаются биты shadow-режима
управление shadow осуществляется автоматически в ПЛИС трансляцией запросов из
177716 и согласно режиму работы маппера в
177346регистр управления маппером 177346 R/WКод
Регистр управления маппером
АДРЕС = 177346
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ ║ │ │ │ ║ ║ │ │ │ │ │ │ │ │ ┌─────────────────────────┐
│ ║ │ │ │ ║ ║ └─────┤ │ │ │ │ └───┴──────┤ версия аппаратной части │
│ ║ │ │ │ ║ ║ │ │ │ │ │ └─────────────────────────┘
│ ║ │ │ │ ║ ║ │ │ │ │ │ ┌─────────────────────────────────┐
│ ║ │ │ │ ║ ║ │ │ │ │ └─────────────┤ =1 50Hz =0 60Hz кадровый таймер │
│ ║ │ │ │ ║ ║ │ │ │ │ └─────────────────────────────────┘
│ ║ │ │ │ ║ ║ │ │ │ │ ┌─────────────────────────────────┐
│ ║ │ │ │ ║ ║ │ │ │ └────────────────┤ =1 включить таймер 100й вектор │
│ ║ │ │ │ ║ ║ │ │ │ └─────────────────────────────────┘
│ ║ │ │ │ ║ ║ │ │ │ ┌────────┐
│ ║ │ │ │ ║ ║ │ │ └───────────────────┤ резерв │
│ ║ │ │ │ ║ ║ │ │ └────────┘
│ ║ │ │ │ ║ ║ │ │ ┌─────────────────────────────────────────────┐
│ ║ │ │ │ ║ ║ │ └───────┤ управление эмуляцией ПЗУ в БК11М =1 включить│
│ ║ │ │ │ ║ ║ │ └─────────────────────────────────────────────┘
│ ║ │ │ │ ║ ║ │ ┌──────────────────────────────────────────────────────────────┐
│ ║ │ │ │ ║ ║ └──┤частота процессора явно те =3 =4 =5 =6 MHz =0 то неопределено │
│ ║ │ │ │ ║ ║ │ заполняется программно, стартовым ПЗУ │
│ ║ │ │ │ ║ ║ └──────────────────────────────────────────────────────────────┘
│ ║ │ │ │ ║ ║ ╔═════════════════════════════════════════════════════════════════════════════════╗
│ ║ │ │ │ ║ ╚══╣ R/W - RAM окно памяти с 0 до 77777 (технически это и окно 100000 до 137777) ║
│ ║ │ │ │ ║ ║ в отключенном режиме (=1) на 037ую не проходят запросы с адресов с 0 до 77777 ║
│ ║ │ │ │ ║ ║ соответственно и 037ая никак не отвечает и не принимает данные на запись ║
│ ║ │ │ │ ║ ║ соответственно эта опция включает RPLY на маппере БК11М, а также возможность ║
│ ║ │ │ │ ║ ║ читать из маппера !!! при 14 бите =0 опция не работает ║
│ ║ │ │ │ ║ ╚═════════════════════════════════════════════════════════════════════════════════╝
│ ║ │ │ │ ║ ╔═════════════════════════════════════════════════════╗
│ ║ │ │ │ ╚═════╣ R/W - ответ на 177660-663 строб 014й =1 отключение ║
│ ║ │ │ │ ║ а именно эмуляцию 014й ║
│ ║ │ │ │ ║ те уже пойдет RPLY от AZ на адресах 177660-663 ║
│ ║ │ │ │ ║ при 14 бите =0 опция не работает ║
│ ║ │ │ │ ╚═════════════════════════════════════════════════════╝
│ ║ │ │ │ ┌──────────────────────────────────────────────────────────────────┐
│ ║ │ │ └──┤ R/W - включение эмуляции БК11М =1 включено │
│ ║ │ │ │эта опция может быть активирована только при наличии =1 в бите 12 │
│ ║ │ │ │(при =0 в бите 12 - игнорируется) │
│ ║ │ │ └──────────────────────────────────────────────────────────────────┘
│ ║ │ │ ┌────────────────────────────────────────────────────────────────┐
│ ║ │ └─────┤ R/W - тип БКшки =0 это 11М, дефолтное состояние =1 это 10ка │
│ ║ │ │ проверяется и устанавливается программно стартовым ПЗУ │
│ ║ │ └────────────────────────────────────────────────────────────────┘
│ ║ │ ┌─────────────────────────────────────────────────────────────────────────────────────────────┐
│ ║ └─┤ 13 - R/W - наличие работоспособной доработки окна1 │
│ ║ │ =1 - работает отключение окна 1 традиционным методом через оттягивание выхода TM9 на землю │
│ ║ │ =0 - доработки нет │
│ ║ │ проверяется и устанавливается программно │
│ ║ │ но сбрасывается в 0 при установке бита 14 - см ниже │
│ ║ └─────────────────────────────────────────────────────────────────────────────────────────────┘
│ ║ ╔═════════════════════════════════════════════════════════╗
│ ╚═╣R/O - тип доработки, результат автоопределения в ПЛИС ║
│ ║=0 доработка окна 1 или нет доработки ║
│ ║=1 доработка с управлением 037й ║
│ ╚═════════════════════════════════════════════════════════╝
│ ┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
└────┤ 15 - R/W - =1 отключение окна 1 в БК11М, транслируется из эмуляции SMK │
│ и в зависимости от типа доработки будет подаваться как сигнал на А22 или как переключение окон 11М │
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
биты
00 - R/O - версия аппаратной части платы ПЛИС - сейчас там 0
01 - R/O - версия аппаратной части платы ПЛИС - сейчас там 0
02 - =1 50Hz =0 60Hz кадровый таймер
переключение источников таймера, в случае 60Гц - оно идет с VGA модуля, 48Гц генерится из 65MHz
03 - =1 включить таймер 100й вектор
включает таймер по 100му вектору безусловно, h
04 - резерв =0
05 - управление эмуляцией ПЗУ в БК11М; по-умолчанию расширенные ПЗУ бейсика подключаемые через 177716 в окно 1 (100000-137777)
ПЗУ 8 [0] - подключает ПЗУ 325, 327 к магистрали
ПЗУ 9 [1] - подключает ПЗУ 328, 329 к магистрали
установка этого бита включает полную эмуляцию подключения этих ПЗУ средствами AZБК
бит независимый от эмуляции БК11М тк может быть случай с БК11М без ПЗУ совсем
частота процессора явно те =3 =4 =5 =6 MHz =0 то неопределено
заполняется программно, стартовым ПЗУ
06 - R/W
07 - R/W
08 - R/W
управление опциями отключения 037й в ПЛИС, доступно программно
по-умолчанию =0, те опция выключена
тк все изначально =0, и устанавливаются по HALT-у
эти опция
отключает прохождение SYNC-а на 037 и
включает дополнительный функционал
09 - R/W - RAM окно памяти с 0 до 77777 (технически это и окно 100000 до 137777)
в отключенном режиме (=1) на 037ую не проходят запросы с адресов с 0 до 77777 соответственно и 037ая никак не отвечает и не принимает данные на запись
соответственно эта опция
включает RPLY на маппере БК11М, а также возможность читать из маппера
при 14 бите =0 опция не работаетэти опция
отключает прохождение SYNC-а на 037 и
включает дополнительный функционал
10 - R/W - ответ на 177660-663 строб 014й =1 отключение
а именно эмуляцию 014й
те уже пойдет RPLY от AZ на адресах 177660-663
при 14 бите =0 опция не работает11 - R/W - включение эмуляции БК11М
=0 выключено
=1 включено
эта опция может быть активирована только при наличии =1 в бите 12 (при =0 в бите 12 - игнорируется)
функционал эмуляции БК11М на БК10 включает:
- разрешение записи (RPLY) в 177662
соответственно работают: палитры + кадровый таймер, частота задается в бите 2
12 - R/W - тип БКшки
=0 это 11М, дефолтное состояние
=1 это 10ка
проверяется и устанавливается программно стартовым ПЗУ
опция нужна для дальнейшей работы механизмов эмуляции БК11М на БК10
наличие в ней =1 обязательно для включения эмуляции БК11М на БК10
13 - R/W - наличие работоспособной доработки окна1
=1 - работает отключение окна 1 традиционным методом через оттягивание выхода TM9 на землю
=0 - доработки нет
проверяется и устанавливается программно
но сбрасывается в 0 при установке бита 14 - см ниже
14 - R/O - тип доработки, результат автоопределения в ПЛИС
=0 доработка окна 1 или нет доработки
=1 доработка с управлением 037й
15 - R/W - =1 отключение окна 1 в БК11М, транслируется из эмуляции SMK
и в зависимости от типа доработки будет подаваться как сигнал на А22 или как переключение окон 11М
Регистры-копии данных, доступны только по чтению
177350 R/O - регистр копия по записи 177130 в режиме записи управления памятью в SMK
177352 R/O - регистр копия по записи 177716 в режиме записи управления памятью в БК11М
Основное назначение регистров - возможность в любой процедуре поменять настройки памяти, что-то сделать и вернуть их обратно (тк штатными средствами узнать что записано в эти регистры невозможно)
Доступные режимы
у нас получается несколько режимов работы доступных для разных конфигураций
a)машина БК11М, без блокировки 037й, возможно наличие простой доработки окна1
доступные режимы
1. теневой маппер БК11М - те ловим DOUT с шины на все окна, RPLY не посылаем
при наличии доработки SMK - отключаем окно аппаратно
б) машина БК11М, с блокировкой 037
1. теневой маппер БК11М - те ловим DOUT с шины на все окна, RPLY не посылаем
2. полный маппер БК11М - те отключаем штатную память полностью, ловим DIN и DOUT с шины на все окна, RPLY посылаем
3. полный маппер БК11М - те отключаем штатную память полностью, ловим DIN и DOUT с шины на все окна, RPLY посылаем, подключаем все "ПЗУ" БК11М (для БК11М без ПЗУ или БК10)
в) машина БК10, без блокировки 037
1. теневой маппер БК10 - те ловим DOUT с шины на все окна, RPLY не посылаем
работаем в режиме обычной расширенной памяти с 120000-157777
г) машина БК10, с блокировкой 037
1. теневой маппер БК10 - те ловим DOUT с шины на все окна, RPLY не посылаем
2. полный маппер БК11М - те отключаем штатную память 037й, ловим DIN и DOUT с шины на все окна, RPLY посылаем
3. полный маппер БК11М - те отключаем штатную память 037й, ловим DIN и DOUT с шины на все окна, RPLY посылаем, подключаем все "ПЗУ" БК11М (для БК11М без ПЗУ или БК10)
Также наличие доработки 037й позволяет отключить 014ую и подключить внешную PS/2 клавиатуру
Техническое описание с точки зрения внутренних механизмов работы маппераданный раздел предназначен для разработки эмуляторов БК с AZ
концепция маппера и работы с памятью
1. вся память доступная AZ, управляется только маппером AZ* доступная AZ - ее объем зависит от конфигурации машины
к примеру
БК-0010(01) без доработки монитора и 037 имеет доступный для работы маппера AZ участок с 120000 и до конца
БК-0010(01) с доработкой монитора и но без доработки 037 имеет доступный для работы маппера AZ участок с 100000 и до конца
БК-0010(01) c доработкой 037 в режиме быстрой памяти или в режиме эмуляции 11М - вся память управляется AZ-маппером
БК11М c доработкой монитора - с 100000 и до конца
БК11М без доработки монитора - с 100000 до 137777 и с 160000 до конца
*управляется маппером AZэто означает что все запросы к 177716 или 177130(SMK) мапперам транслируются в запросы к мапперу AZ
2. Гранулярность окон маппера - 4кБ - это позволяет легко рулить всей доступной памятью
единственное ограничение - окно 170000 имеет принудительное окончание на 176777
3. Маппер имеет возможность назначения режимов для каждого окнаэто очень важно понимать для понимания работы всего маппера
4. Регистры маппераони описаны выше но повторю:
177300-177336 - адрес начала окна
177340 - регистр активного RPLY
177342 - регистр ограничения R/O
177344 - регистр теневой записи - shadow
177346 - управление маппером
также есть регистры-справки
177350 R/O - регистр копия по записи 177130 в режиме записи управления памятью в SMK
177352 R/O - регистр копия по записи 177716 в режиме записи управления памятью в БК11М
приоритеты:для исключения конфликтов
177340 имеет больший приоритет чем
177344
тут все ясно и описано ранее
5. Работа внутренних механизмов - эмуляция маппера 11Мтут разберем как обрабатываются запросы к мапперу 11М в AZ
- обращение к 177716 разделяются на 2 ветки - DIN (чтение) и DOUT (запись)
5.1 DINкод обработчика DIN - те стейт
state==STATE_DIN_reg_az_716Код
if (state==STATE_DIN_reg_az_716)
begin
DA_OUT[15]<=1'b1;
DA_OUT[14:12]<=(start==1)?3'd7: // если старт - 170
(reg_az_mapper_ctrl[14]==1 && // есть доработка 037й
reg_az_mapper_ctrl[9]==1 && // отключена 037ая
reg_az_mapper_ctrl[11]==1)?3'd4: // включена эмуляция 11М - 140
3'd0; // иначе 100k
DA_OUT[11:7]<={4'd0,1'b1};
DA_OUT[6]<= (reg_az_mapper_ctrl[10]==1)?~key_down:1'd0; // отдаем нажатие только когда у нас PS/2 - иначе не мешаем работать
DA_OUT[5:0]<=6'd0;
end
пояснения
DA_OUT - это данные на шину, те что AZ отдает процессору
eg_az_mapper_ctr - это регистр 177446
5.2 DOUTтут все сложнее
сначала идет фильтрация - те для перехода в стейт
state=STATE_DOUT_reg_az_716
недостаточно упавшего B_DOUT_L, нужно еще выполнение условий:
Код
if (B_DOUT_L==0 && (DA_IN[11]==1) && // это флаг записи в 177716!
( reg_az_mapper_ctrl[12]==0 || // или это БК11М
( reg_az_mapper_ctrl[9]==1 // или замена памяти 037 +
&& reg_az_mapper_ctrl[12]==1 // это БК10 +
&& reg_az_mapper_ctrl[14]==1 // есть доработка 037й
)))
next_state=STATE_DOUT_reg_az_716;
если условия выполнены, мы попадает на стейт
state=STATE_DOUT_reg_az_716
важно стейт не единственный - это цепочка:
Код
STATE_DOUT_reg_az_716: // запись в 177716
next_state=STATE_DOUT_reg_az_716_pre;
STATE_DOUT_reg_az_716_pre: // формируем регистры PRE для AZ
next_state=STATE_DOUT_reg_az_716_az;
STATE_DOUT_reg_az_716_az: // запись PRE в регистры маппера AZ
next_state=STATE_WAITSYNC1;
первый стейт STATE_DOUT_reg_az_716 - это проверка условий обращения к мапперу (те бит 11)
далее стейт формирования PRE регистров данных
это регистры-предшественники с данными для маппера AZ
и третий стейт это непосредственно запись регистров-предшественников в регистры маппера AZ
итак идетм по стейтам
5.2.1 STATE_DOUT_reg_az_716Код
[code]
always @ (posedge CLK)
begin
if ( (state==STATE_DOUT_reg_az_716) && (DA_IN[11]==1) )
reg_az_716<=DA_IN[15:0]; // запоминаем только при обращении к мапперу памяти
end
5.2.2 STATE_DOUT_reg_az_716_preа вот тут уже сложнее
Код
wire [2:0] win0_map={reg_az_716[14],reg_az_716[13],reg_az_716[12]}; // что подключено в окно 0: 40000 - 77777
wire [2:0] win1_map={reg_az_716[10],reg_az_716[9], reg_az_716[8] }; // что подключено в окно 1: 100000 - 137777
wire win1_roms01=reg_az_716[0] || reg_az_716[1];// флаг подключения ПЗУ 11М (бейсик и БОС) в окно1: 100000 - 137777
wire win1_roms34=reg_az_716[3] || reg_az_716[4];// флаг подключения внешних ПЗУ в окно1: 100000 - 137777
reg [6:0] pre_b11m_reg_az_mapper[7:0]; // массив регистров мапирования // сохраняем младшие 7бит и только 8 регистров
reg pre_b11m_reg_az_win_ctrl; // регистр для установки режимов окна 1 - активность
reg pre_b11m_reg_az_win_shdw; // регистр для установки режимов окна 1 - тень
always @ (posedge CLK)
begin
if (state==STATE_DOUT_reg_az_716_pre)
begin
pre_b11m_reg_az_mapper[3'd0]<={2'd0,win0_map,2'd0}; // что подключено в окно 0: 40000 - 77777
pre_b11m_reg_az_mapper[3'd1]<={2'd0,win0_map,2'd1};
pre_b11m_reg_az_mapper[3'd2]<={2'd0,win0_map,2'd2};
pre_b11m_reg_az_mapper[3'd3]<={2'd0,win0_map,2'd3};
pre_b11m_reg_az_mapper[3'd4]<=(reg_az_716[1]==1)?7'o124:(reg_az_716[0]==1)?7'o126:{2'd0,win1_map,2'd0}; // что подключено в окно 1: 100000 - 137777
pre_b11m_reg_az_mapper[3'd5]<=(reg_az_716[1]==1)?7'o125:(reg_az_716[0]==1)?7'o127:{2'd0,win1_map,2'd1}; // 110000
pre_b11m_reg_az_mapper[3'd6]<=(reg_az_716[1]==1)?7'o122:(reg_az_716[0]==1)?7'o130:{2'd0,win1_map,2'd2}; // 120000
pre_b11m_reg_az_mapper[3'd7]<=(reg_az_716[1]==1)?7'o123:(reg_az_716[0]==1)?7'o131:{2'd0,win1_map,2'd3}; // 130000
pre_b11m_reg_az_win_ctrl<=(win1_roms01==1)?reg_az_mapper_ctrl[5]: // если были запрошены ПЗУ 11М даем их если есть разрешение
(win1_roms34==1)?1'b0: // если были запрошены внешние ПЗУ11М - нету нифига!
reg_az_mapper_ctrl[9]; // тогда ОЗУ и то только если оно включено
pre_b11m_reg_az_win_shdw<=(win1_roms01==1 || win1_roms34==1)?1'b0: // для любых ПЗУ нет shadow
~reg_az_mapper_ctrl[9]; // если оперативка не в активном состоянии- то значит shadow
end
end
//
5.2.3 STATE_DOUT_reg_az_716_azэтот стейт сложнее - тут идет непосредственно применение PRE-регистров
Код
if (state==STATE_DOUT_reg_az_716_az) // есть преобразование от БК11М
begin // регистры идут обрезанные - 12шт по 6бит
// начальный блок статика - всегда приколочен жестко
reg_az_mapper[4'd0] <=13'o030; // 000000-007777
reg_az_mapper[4'd1] <=13'o031; // 010000-017777
reg_az_mapper[4'd2] <=13'o032; // 020000-027777
reg_az_mapper[4'd3] <=13'o033; // 030000-037777
// окно 0 - всегда оперативка
reg_az_mapper[4'd4] <={6'd0,pre_b11m_reg_az_mapper[4'd0]}; // 040000-047777
reg_az_mapper[4'd5] <={6'd0,pre_b11m_reg_az_mapper[4'd1]}; // 050000-057777
reg_az_mapper[4'd6] <={6'd0,pre_b11m_reg_az_mapper[4'd2]}; // 060000-067777
reg_az_mapper[4'd7] <={6'd0,pre_b11m_reg_az_mapper[4'd3]}; // 070000-077777
reg_az_win_ctrl[7:0] <={8{reg_az_mapper_ctrl[9]}}; // если включена замена 037 - включаем оперативку как активную
reg_az_win_ro[7:0] <=8'd0; // сбрасываем на всякий случай флаг запрета записи
reg_az_win_shdw[7:0] <={8{~reg_az_mapper_ctrl[9]}}; // если нет замены - включаем shadow
if (reg_az_mapper_ctrl[15]==0) // нет сигнала отключения окна 1 от SMK
begin
// окно 1 - может отключаться или эмулировать ПЗУ. адреса пишем всегда
reg_az_mapper[4'd8] <={6'd0,pre_b11m_reg_az_mapper[4'd4]}; // 100000-107777
reg_az_mapper[4'd9] <={6'd0,pre_b11m_reg_az_mapper[4'd5]}; // 110000-117777
reg_az_mapper[4'd10] <={6'd0,pre_b11m_reg_az_mapper[4'd6]}; // 120000-127777
reg_az_mapper[4'd11] <={6'd0,pre_b11m_reg_az_mapper[4'd7]}; // 130000-137777
reg_az_win_ctrl[11:8] <={4{pre_b11m_reg_az_win_ctrl}};
reg_az_win_ro [11:8] <=4'd0; // сбрасываем на всякий случай флаг запрета записи
reg_az_win_shdw[11:8] <={4{pre_b11m_reg_az_win_shdw}};
end
else
begin // окно отключено через SMK - значит вставляем данные от SMK-маппера
reg_az_mapper[4'd11] <={5'b00000,pre_smk_reg_az_mapper[3'd3]}; // 130000-137777
reg_az_mapper[4'd10] <={5'b00000,pre_smk_reg_az_mapper[3'd2]}; // 120000-127777
reg_az_mapper[4'd9] <={5'b00000,pre_smk_reg_az_mapper[3'd1]}; // 110000-117777
reg_az_mapper[4'd8] <={5'b00000,pre_smk_reg_az_mapper[3'd0]}; // 100000-107777
reg_az_win_ctrl[11:8] <=pre_smk_reg_az_win_ctrl[3:0];
reg_az_win_ro [11:8] <=pre_smk_reg_az_win_ro [3:0];
reg_az_win_shdw[11:8] <=4'b0000;
end
тут видно, что маппер SMK тут тоже завязан ибо он "надет сверху" на маппер 11М и подменяет окно1 когда хочет
6. работа внутренних механизмов - эмуляция маппера SMK
чтение из 177130 у нас не поддерживается соответственно тут только участок обработки DOUT
тут тоже цепочка стейтов
Код
// 177130
STATE_DOUT_reg_az_130:
if(reg_az_smk_flag==1 ) // флаг установлен ?
next_state=STATE_DOUT_reg_az_130_wsmk;
else
next_state=STATE_DOUT_reg_az_130_wflg;// не установлен, проверяем возможность установки
STATE_DOUT_reg_az_130_wflg: // если флаг не установлен - пытаемся его установить
next_state=STATE_WAITSYNC1;
STATE_DOUT_reg_az_130_wsmk: // флаг установлен - читаем данные в регистр SMK
next_state=STATE_DOUT_reg_az_130_pre;
STATE_DOUT_reg_az_130_pre: // формируем регистры PRE для AZ
next_state=STATE_DOUT_reg_az_130_az;
STATE_DOUT_reg_az_130_az: // запись PRE в регистры маппера AZ
next_state=STATE_WAITSYNC1;
описание стейтов
Код
localparam STATE_DOUT_reg_az_130 = 6'd35; // опрос флага SMK
localparam STATE_DOUT_reg_az_130_wflg = 6'd36; // если флаг не установлен - пытаемся его установить
localparam STATE_DOUT_reg_az_130_wsmk = 6'd37; // флаг установлен - читаем данные в регистр SMK
localparam STATE_DOUT_reg_az_130_pre = 6'd38; // формируем регистры PRE
localparam STATE_DOUT_reg_az_130_az = 6'd39; // пишем PRE в маппер
6.1 STATE_DOUT_reg_az_130это промежуточный стейт
6.2 STATE_DOUT_reg_az_130_wflgКод
// установка флага
always @ (posedge CLK)
begin
if (state==STATE_DOUT_reg_az_130_wflg) // если флаг не установлен - пытаемся его установить
reg_az_smk_flag<=(DA_IN==16'o6); // если в 177130 пишется 6 то это флаг
else if ( (state==STATE_DOUT_reg_az_130_az) || (state_hlt==STATE_HLT_HALT1) )
reg_az_smk_flag<=1'b0; // а тут сбрасываем флаг
end
те обработка флага записи
6.3 STATE_DOUT_reg_az_130_wsmkКод
// сохранение данных в регистр SMK
always @ (posedge CLK)
begin
if (state==STATE_DOUT_reg_az_130_wsmk) // флаг установлен - читаем данные в регистр SMK
reg_az_reg_az_smk_data<=DA_IN;
end
//
6.4 STATE_DOUT_reg_az_130_preпромежуточный стейт, во время которого происходит формирование PRE- данных по SMK
Код
// формирование отключения (1)
// МОНБК10 = ( ~U2 && ~U1 ) || ( U2 && ~U1);
// МОНБК11М = ( ~U2 && ~U1 ) || (~U2 && U1)
// ОКНОБК11M = U0
wire mon_bk10_off= ( ~reg_az_reg_az_smk_data[6] && ~reg_az_reg_az_smk_data[5] ) || ( reg_az_reg_az_smk_data[6] && ~reg_az_reg_az_smk_data[5] );
wire mon_bk11m_off= ( ~reg_az_reg_az_smk_data[6] && ~reg_az_reg_az_smk_data[5] ) || ( ~reg_az_reg_az_smk_data[6] && reg_az_reg_az_smk_data[5] );
wire [3:0] SMK_PAGE={reg_az_reg_az_smk_data[10],reg_az_reg_az_smk_data[3],reg_az_reg_az_smk_data[2],reg_az_reg_az_smk_data[0]}; // номер страницы памяти, страница по 32кБ * 16шт всего 512кБ
// для SMK выделен блок с 512кБ до 1024кБ - итоговые внутренние номера сегментов от 200 до 377
// блок режимов U2 U1 U0
wire [2:0] SMK_MODE={reg_az_reg_az_smk_data[6],reg_az_reg_az_smk_data[5],reg_az_reg_az_smk_data[4]}; // номер режима
// набор регистров которые будут транслироваться из SMK в регистры AZ после операции SMK
reg [7:0] pre_smk_reg_az_mapper[7:0]; // массив регистров мапирования // сохраняем младшие 13бит // регистры только старшие
reg [7:0] pre_smk_reg_az_win_ctrl; // управление окнами - битовая маска активации окон, верхняя часть
reg [7:0] pre_smk_reg_az_win_ro; // управление окнами - битовая маска r/o окон, верхняя часть
reg [11:8] pre_smk_reg_az_win_shdw; // управление тенью
always @ *
begin
case (SMK_MODE)
3'b111: // Start - используется для запуска, пересылки данных на БК10 и RAM-BIOS'ом (он - всегда в 0-й странице);
begin
pre_smk_reg_az_mapper[3'd7]<=8'o100;
pre_smk_reg_az_mapper[3'd6]<=8'o110;
pre_smk_reg_az_mapper[3'd5]<={1'b1,SMK_PAGE,3'd1}; // 4+3=7bit
pre_smk_reg_az_mapper[3'd4]<={1'b1,SMK_PAGE,3'd0};
pre_smk_reg_az_mapper[3'd3]<={1'b1,SMK_PAGE,3'd7};
pre_smk_reg_az_mapper[3'd2]<={1'b1,SMK_PAGE,3'd6};
//pre_smk_reg_az_mapper[3'd1]<=pre_smk_reg_az_mapper[3'd1];
//pre_smk_reg_az_mapper[3'd0]<=pre_smk_reg_az_mapper[3'd0];
pre_smk_reg_az_win_ctrl <=8'b11111100;
pre_smk_reg_az_win_ro <=8'b00000000;
end
3'b011: // Std10 60
begin
pre_smk_reg_az_mapper[3'd7]<={1'b1,SMK_PAGE,3'd7};
pre_smk_reg_az_mapper[3'd6]<=8'o110;
pre_smk_reg_az_mapper[3'd5]<={1'b1,SMK_PAGE,3'd5};
pre_smk_reg_az_mapper[3'd4]<={1'b1,SMK_PAGE,3'd4};
pre_smk_reg_az_mapper[3'd3]<={1'b1,SMK_PAGE,3'd3};
pre_smk_reg_az_mapper[3'd2]<={1'b1,SMK_PAGE,3'd2};
//pre_smk_reg_az_mapper[3'd1]<=pre_smk_reg_az_mapper[3'd1];
//pre_smk_reg_az_mapper[3'd0]<=pre_smk_reg_az_mapper[3'd0];
pre_smk_reg_az_win_ctrl <=8'b11111100;
pre_smk_reg_az_win_ro <=8'b00000000;
end
3'b101: // ОЗУ10 120
begin
pre_smk_reg_az_mapper[3'd7]<={1'b1,SMK_PAGE,3'd7};
pre_smk_reg_az_mapper[3'd6]<={1'b1,SMK_PAGE,3'd6};
pre_smk_reg_az_mapper[3'd5]<={1'b1,SMK_PAGE,3'd5};
pre_smk_reg_az_mapper[3'd4]<={1'b1,SMK_PAGE,3'd4};
pre_smk_reg_az_mapper[3'd3]<={1'b1,SMK_PAGE,3'd3};
pre_smk_reg_az_mapper[3'd2]<={1'b1,SMK_PAGE,3'd2};
pre_smk_reg_az_mapper[3'd1]<={1'b1,SMK_PAGE,3'd1};
pre_smk_reg_az_mapper[3'd0]<={1'b1,SMK_PAGE,3'd0};
pre_smk_reg_az_win_ctrl <=8'b11111111;
pre_smk_reg_az_win_ro <=8'b00000000;
end
3'b001: // All 20
begin
pre_smk_reg_az_mapper[3'd7]<={1'b1,SMK_PAGE,3'd3};
pre_smk_reg_az_mapper[3'd6]<={1'b1,SMK_PAGE,3'd2};
pre_smk_reg_az_mapper[3'd5]<={1'b1,SMK_PAGE,3'd1};
pre_smk_reg_az_mapper[3'd4]<={1'b1,SMK_PAGE,3'd0};
pre_smk_reg_az_mapper[3'd3]<={1'b1,SMK_PAGE,3'd7};
pre_smk_reg_az_mapper[3'd2]<={1'b1,SMK_PAGE,3'd6};
pre_smk_reg_az_mapper[3'd1]<={1'b1,SMK_PAGE,3'd5};
pre_smk_reg_az_mapper[3'd0]<={1'b1,SMK_PAGE,3'd4};
pre_smk_reg_az_win_ctrl <=8'b11111111;
pre_smk_reg_az_win_ro <=8'b00000000;
end
3'b110: // Std11 140
begin
pre_smk_reg_az_mapper[3'd7]<={1'b1,SMK_PAGE,3'd7};
pre_smk_reg_az_mapper[3'd6]<=8'o110;
pre_smk_reg_az_mapper[3'd5]<=8'o121; // стандартное ПЗУ БК11М
pre_smk_reg_az_mapper[3'd4]<=8'o120; // стандартное ПЗУ БК11М
//pre_smk_reg_az_mapper[3'd3]<=pre_smk_reg_az_mapper[3'd3];
//pre_smk_reg_az_mapper[3'd2]<=pre_smk_reg_az_mapper[3'd2];
//pre_smk_reg_az_mapper[3'd1]<=pre_smk_reg_az_mapper[3'd1];
//pre_smk_reg_az_mapper[3'd0]<=pre_smk_reg_az_mapper[3'd0];
pre_smk_reg_az_win_ctrl <=8'b11110000;
pre_smk_reg_az_win_ro <=8'b00000000;
end
3'b010: // ОЗУ11 40
begin
pre_smk_reg_az_mapper[3'd7]<={1'b1,SMK_PAGE,3'd7};
pre_smk_reg_az_mapper[3'd6]<={1'b1,SMK_PAGE,3'd6};
pre_smk_reg_az_mapper[3'd5]<={1'b1,SMK_PAGE,3'd5};
pre_smk_reg_az_mapper[3'd4]<={1'b1,SMK_PAGE,3'd4};
//pre_smk_reg_az_mapper[3'd3]<=pre_smk_reg_az_mapper[3'd3];
//pre_smk_reg_az_mapper[3'd2]<=pre_smk_reg_az_mapper[3'd2];
//pre_smk_reg_az_mapper[3'd1]<=pre_smk_reg_az_mapper[3'd1];
//pre_smk_reg_az_mapper[3'd0]<=pre_smk_reg_az_mapper[3'd0];
pre_smk_reg_az_win_ctrl <=8'b11110000;
pre_smk_reg_az_win_ro <=8'b00000000;
end
3'b100: // HLT10 100
begin
pre_smk_reg_az_mapper[3'd7]<={1'b1,SMK_PAGE,3'd7};
pre_smk_reg_az_mapper[3'd6]<={1'b1,SMK_PAGE,3'd6};
pre_smk_reg_az_mapper[3'd5]<={1'b1,SMK_PAGE,3'd5};
pre_smk_reg_az_mapper[3'd4]<={1'b1,SMK_PAGE,3'd4};
pre_smk_reg_az_mapper[3'd3]<={1'b1,SMK_PAGE,3'd3};
pre_smk_reg_az_mapper[3'd2]<={1'b1,SMK_PAGE,3'd2};
pre_smk_reg_az_mapper[3'd1]<={1'b1,SMK_PAGE,3'd1};
pre_smk_reg_az_mapper[3'd0]<={1'b1,SMK_PAGE,3'd0};
pre_smk_reg_az_win_ctrl <=8'b11111111;
pre_smk_reg_az_win_ro <=8'b00000001;
end
3'b000: // HLT11 20000 = 0
begin
pre_smk_reg_az_mapper[3'd7]<={1'b1,SMK_PAGE,3'd7};
pre_smk_reg_az_mapper[3'd6]<={1'b1,SMK_PAGE,3'd6};
pre_smk_reg_az_mapper[3'd5]<={1'b1,SMK_PAGE,3'd5};
pre_smk_reg_az_mapper[3'd4]<={1'b1,SMK_PAGE,3'd4};
//pre_smk_reg_az_mapper[3'd3]<=pre_smk_reg_az_mapper[3'd3];
//pre_smk_reg_az_mapper[3'd2]<=pre_smk_reg_az_mapper[3'd2];
//pre_smk_reg_az_mapper[3'd1]<=pre_smk_reg_az_mapper[3'd1];
//pre_smk_reg_az_mapper[3'd0]<=pre_smk_reg_az_mapper[3'd0];
pre_smk_reg_az_win_ctrl <=8'b11110000;
pre_smk_reg_az_win_ro <=8'b00000000;
end
endcase
end
//
6.5 STATE_DOUT_reg_az_130_azа вот тут уже применением PRE регистров:
Код
if (state==STATE_DOUT_reg_az_130_az) // есть преобразование от SMK
begin
reg_az_mapper[4'd15] <={5'b00000,pre_smk_reg_az_mapper[3'd7]}; // 170000-177000
reg_az_mapper[4'd14] <={5'b00000,pre_smk_reg_az_mapper[3'd6]}; // 160000-167777
reg_az_mapper[4'd13] <={5'b00000,pre_smk_reg_az_mapper[3'd5]}; // 150000-157777
reg_az_mapper[4'd12] <={5'b00000,pre_smk_reg_az_mapper[3'd4]}; // 140000-147777
reg_az_win_ctrl[15:12] <=pre_smk_reg_az_win_ctrl[7:4];
reg_az_win_ro [15:12] <=pre_smk_reg_az_win_ro [7:4];
reg_az_win_shdw[15:12] <=5'd0; // принудительно выключаем тень тк вся память SMK это память AZ
if (reg_az_reg_az_smk_data[4]==1) // есть отключение окна 1 и мы оверайдим из SMK данные
begin
reg_az_mapper[4'd11] <={5'b00000,pre_smk_reg_az_mapper[3'd3]}; // 130000-137777
reg_az_mapper[4'd10] <={5'b00000,pre_smk_reg_az_mapper[3'd2]}; // 120000-127777
reg_az_mapper[4'd9] <={5'b00000,pre_smk_reg_az_mapper[3'd1]}; // 110000-117777
reg_az_mapper[4'd8] <={5'b00000,pre_smk_reg_az_mapper[3'd0]}; // 100000-107777
reg_az_win_ctrl[11:8] <=pre_smk_reg_az_win_ctrl[3:0];
reg_az_win_ro [11:8] <=pre_smk_reg_az_win_ro [3:0];
reg_az_win_shdw[11:8] <=4'b0000; // принудительно выключаем тень в зоне пересечения с SMK - те на окне 1
end
else // иначе окно принадлежит мапперу БК11М
begin
// окно 1 - может отключаться или эмулировать ПЗУ. адреса пишем всегда
reg_az_mapper[4'd8] <={6'd0,pre_b11m_reg_az_mapper[4'd4]}; // 100000-107777
reg_az_mapper[4'd9] <={6'd0,pre_b11m_reg_az_mapper[4'd5]}; // 110000-117777
reg_az_mapper[4'd10] <={6'd0,pre_b11m_reg_az_mapper[4'd6]}; // 120000-127777
reg_az_mapper[4'd11] <={6'd0,pre_b11m_reg_az_mapper[4'd7]}; // 130000-137777
reg_az_win_ctrl[11:8] <={4{pre_b11m_reg_az_win_ctrl}};
reg_az_win_ro [11:8] <=4'd0; // сбрасываем на всякий случай флаг запрета записи
reg_az_win_shdw[11:8] <={4{pre_b11m_reg_az_win_shdw}};
end
reg_az_mapper_ctrl[15]<=reg_az_reg_az_smk_data[4]; // отключение окна 1 на БК11М
end
7. внутренние механизмы - старт БКшкитут стоит подробно описать как производится старт AZ и БК
следует выделить несолько этапов, перывым из которых является - инзкий HALT
7.1 микроконтроллер (далее МК) обнаружив низкий HALT перезапусается
7.2 после перезапуска МК сам устанавливает низкий HALT для удержания БК в остановленном состоянии. в это время МК инициализиует библитеку FATFS, сеть, и загружает с карточки из директории ROM все ПЗУ которые описаны в AZ.INI
после завершения инциализации, МК отпускает HALT БКшки и она начинает стартовать
ПЛИС в это время "выполняет" вот этот код
Код
if (state_hlt==STATE_HLT_HALT1) // установка стартовой конфигурации, далее уже стартовое ПЗУ все настраивает
begin
reg_az_mapper[4'd15] <=13'o100; // подключаем стартовое ПЗУ - страница 100
reg_az_win_ctrl <=16'o100000; // активируем стартовое ПЗУ
reg_az_mapper_ctrl[15] <=1'b0; // сбрасываем блокировку окна 1 в БК11М
reg_az_mapper_ctrl[3] <=1'b0; // выключаем кадровый таймер явно
reg_az_mapper_ctrl[14] <=~WIN1_OFF; // считаем состояние доработки
reg_az_mapper_ctrl[13] <=(~WIN1_OFF==1)?1'b0:reg_az_mapper_ctrl[13]; // сбросим если есть доработка 037й
reg_az_mapper_ctrl[10:9]<=2'b0; // сбросим режимы доработки в первоначальное состояние
end
7.3 старт процессора БК идет согласно ответа на 177716 - см выше мы описали условия ответа.
в данном случае AZ явно устанавливает старший байт адреса запуска в 170000
программа старта проверяет начилие установленной частоты процессора в 177346 и если там пусто - пишет туда 7, устанавливает начальное значение маппера 177716 и отправляет БК в перезапуск командой микроконтроллеру.
это сделано для первоначальной инициализации регистра 177716 который при первом включении БК11М находится в некоррекном состоянии - а именно он включает все ПЗУ на шину!
если не привести его в порядок, механизм автоопределения доработки примет 11М за БК10 что нарушит работу маппера.
7.4 БК перезапускается те пункты 7.1->7.2->7.3->
теперь процессор снова стартанул со 170000 и тут код уже видит что в частоте стоит 7 и первичная инициализация проведена успешно и начинается выполнение основного кода старта БК
8. защита от дуракаэтот блок описывает защиты от некорректных установок в 177346
Код
// сюда попадаем только при 14=1 и 10=1
STATE_PRC_reg_az_014_662:
if(B_DIN_L==0 )
next_state=STATE_DIN_reg_az_014_662;
else
if (B_DOUT_L==0 &&
( ( reg_az_mapper_ctrl[11]==1 && reg_az_mapper_ctrl[12]==1 ) || // включаем запись в 177662 при эмуляции БК11М на БК10
( reg_az_mapper_ctrl[11]==0 && reg_az_mapper_ctrl[12]==0 ) ) // включаем запись в 177662 на 11М при отключенной эмуляции 10ки
)
next_state=STATE_DOUT_reg_az_014_662;
else
if (B_SYNC_L==1)
next_state=STATE_WAITSYNC1;
else
next_state=STATE_PRC_reg_az_014_662;
Код
STATE_PRC_reg_az_716:
if ((B_DIN_L==0) )// && (start==1) )
next_state=STATE_DIN_reg_az_716;
else
if (B_DOUT_L==0 && (DA_IN[11]==1) && // это флаг записи в 177716!
( reg_az_mapper_ctrl[12]==0 || // или это БК11М
( reg_az_mapper_ctrl[9]==1 // или замена памяти 037 +
&& reg_az_mapper_ctrl[12]==1 // это БК10 +
&& reg_az_mapper_ctrl[14]==1 // есть доработка 037й
)))
next_state=STATE_DOUT_reg_az_716;
else
if (B_SYNC_L==1)
next_state=STATE_WAITSYNC1;
else
next_state=STATE_PRC_reg_az_716;
Дополнительные материалы:
Маппер БК11М
Код
РАСПРЕДЕЛEНИЕ АДРЕСНОГО ПРОСТРАНСТВА БК11М
окно N%0 окно N%1
0 40000 100000 140000 160000 177777
┌──────────────┬─────────────┬─────────────┬────────────┬────────────┐
│ стр ОЗУ 0 │ ХХХХХХ │ ХХХХХХ │ сист. ПЗУ │регистры ВУ│
└──────────────┴─────────────┴─────────────┴────────────┴────────────┘
│ │
┌───────┘ └────────┐
┌─────────────┴────────────┐ ┌────────────┴────────────┐
│ стр ОЗУ 0....7 │ │ стр ОЗУ 0....7 │
└──────────────────────────┘ └─────────────────────────┘
или
┌─────────────────────────┐
│ стр ПЗУ 8....11 │
└─────────────────────────┘
┌─────────────────────────────────────────────┐
│ 177716 по записи, при установленом бите 11 │
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
┌───────────────────────┐ │││││││ │ ││││││ │ │ │ │
│ окно ОЗУ N%0 ├───┴─────┘ │ │ │ │ │ │ │
└───────────────────────┘ │ │ │ │ │ │ │
┌───────────────────────┐ │ │ │ │ │ │ │
│ окно ОЗУ N%1 ├────────────│──┴────┘ │ │ │ │
└───────────────────────┘ │ │ │ │ │
┌───────────────────────┐ │ │ │ │ │
│ стробирование записи ├────────────┘ │ │ │ │
└───────────────────────┘ │ │ │ │
┌─────────────────────────────────────────────────────────────────────┐
│ подключение стр. ППЗУ NN% по адресу 100000-140000 11..10...9..8│
└─────────────────────────────────────────────────────────────────────┘
КОДИРОВКА ПЕРЕКЛЮЧАЕМЫХ СТАНИЦ ОЗУ
┌────────────────┬──────────────────┬────────────────┬─────────────────┬─────────────────┐
│ НОМЕР СТРАНИЦЫ │ МАСКА (14;13;12) │ МАСКА (10,9,8) │ СТАТУС │Номер страницы AZ│
├────────────────┼──────────────────┼────────────────┼─────────────────┼─────────────────┤
│ 0 │ 60000 (110) │ 3000 │ отображена │ 030 │
│ │ │ │ 0....40000 │ │
│ 1 │ 00000 (000) │ 0000 │ │ 000 │
│ │ │ │ │ │
│ 2 │ 20000 (010) │ 1000 │ │ 010 │
│ │ │ │ │ │
│ 3 │ 30000 (011) │ 1400 │ │ 014 │
│ │ │ │ │ │
│ 4 │ 40000 (100) │ 2000 │ │ 020 │
│ │ │ │ │ │
│ 5 │ 10000 (001) │ 0400 │ БУФЕР ЭКРАНА 0 │ 004 │
│ │ │ │ │ │
│ 6 │ 70000 (111) │ 3400 │ БУФЕР ЭКРАНА 1 │ 034 │
│ │ │ │ │ │
│ 7 │ 50000 (101) │ 2400 │ │ 024 │
└────────────────┴──────────────────┴────────────────┴─────────────────┴─────────────────┘
* ВНИМАНИЕ ! маска указана без учета бита 11 (4000)
ПЗУ 8[0] - подключает ПЗУ 328, 329 к магистрали - 100k=328 120k=329
ПЗУ 9[1] - подключает ПЗУ 325, 327 к магистрали - 100k=327 120k=325
ПЗУ 10[3] - внешнее пзу в панельках (2шт) или на МПИ, сигнал разрешения на A32
ПЗУ 11[4] - внешнее пзу на МПИ, сигнал разрешения на A22 (ПЗУ ЛВС)
наличие сигнала выбора ПЗУ, отключает ОЗУ с 100000
ПЗУ
R16=0:/rom/11m_324.rom 120 121 - 140k
R18=0:/rom/11m_325.rom 122 123 - 120k
R20=0:/rom/11m_327.rom 124 125 - 100k
R22=0:/rom/11m_328.rom 126 127 - 100k
R24=0:/rom/11m_329.rom 130 131 - 120k
Автор: SuperMax 17.6.2022, 20:18
К расширенным видеорежимам добавились слои (редакция от 2024-05-05)
теперь вот так:
177230 - регистр управления
177232 - регистр номера страницы начала отображения - верхняя страница (слой 0)
177240 - регистр номера страницы начала отображения - средняя страница (слой 1) "под спрайты"
177242 - регистр номера страницы начала отображения - нижняя страница (слой 2) "под фон"
177244 - регистр вертикального скролинга слой 2
177246 - регистр вертикального скролинга слой 1
177250 - регистр вертикального скролинга слой 0
177252 - регистр гозизонтального скролинга слой 0
177254 - регистр гозизонтального скролинга слой 1
177256 - регистр гозизонтального скролинга слой 2
Код
РЕГИСТР УПРАВЛЕНИЯ ВИДЕОКОНТРОЛЛЕРОМ
АДРЕС = 177230
ФОРМАТ РЕГИСТРА
доступен по чтению и записи
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐ ┌────────────────────┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│ │ 0 - 1 бит на цвет*│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘ │ 1 - 2 бита на цвет │
║ ║ ║ │ │ │ │ │ │ ║ │ │ │ 2 - 4 бита на цвет │
║ ║ ║ └───┤ └───┤ └───┤ ║ └───┴──┤ 3 - 8 бит на цвет │
╠════════╝ ║ │ │ │ ║ └────────────────────┘
║ ║ │ │ │ ║ ┌────────────────────┐
║ ║ │ │ │ ╚═════════╡ =1 слоеный режим │
║ ║ │ │ │ └────────────────────┘
║ ║ │ │ │ ┌─────────────────────┐
║ ║ │ │ └───────────┤ 0 - 32 слова │
║ ║ │ │ │ 1 - 64 слова │
║ ║ │ │ │ 2 - 128 слов │
║ ║ │ │ │ 3 - 256 слов │
║ ║ │ │ └─────────────────────┘
║ ║ │ │ ┌─────────────────────┐
║ ║ │ └────────────────────┤ 0 - х1 - 1024 точки │
║ ║ │ │ 1 - х2 - 512 точки │
║ ║ │ │ 2 - х3 - 256 точки │
║ ║ │ │ 3 - х4 - 128 точки │
║ ║ │ └─────────────────────┘
║ ║ │ ┌───────────────────────────┐
║ ║ └─┤ 0 - х1 - 768 строк │
║ ║ │ 1 - х2 - 384 строк │
║ ║ │ 2 - х3 - 256 строк │
║ ║ │ 3 - х4 - 192 строк │
║ ║ └───────────────────────────┘
║ ║ ┌───────────────────────────┐
║ ╚════════╡ Управление синхронизацией │
║ │ =1 включена │
║ └───────────────────────────┘
║╔═════════════════════════╗
╚╣ длина рулона в словах ║
║ 0 6144 ║
║ 1 8192 ║
║ 2 12288 ║
║ 3 16384 ║
║ 4 24576 ║
║ 5 32768 ║
║ 6 49152 ║
║ 7 65536 ║
║ 8. 98304 ║
║ 9. 131072 ║
║ 10. 196608 ║
║ 11. 262144 ║
╚═════════════════════════╝
РЕГИСТР ОСНОВНОЙ (ВЕРХНЕЙ) СТРАНИЦЫ ОТОБРАЖЕНИЯ
АДРЕС = 177232
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└──────────НОМЕР СТРАНИЦЫ ───────────┘
РЕГИСТР СРЕДНЕЙ СТРАНИЦЫ ОТОБРАЖЕНИЯ
АДРЕС = 177240
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└──────────НОМЕР СТРАНИЦЫ ───────────┘
РЕГИСТР НИЖНЕЙ СТРАНИЦЫ ОТОБРАЖЕНИЯ
АДРЕС = 177242
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└──────────НОМЕР СТРАНИЦЫ ───────────┘
РЕГИСТР ВЕРТИКАЛЬНОГО СКРОЛЛИНГА СЛОЙ 2
АДРЕС = 177244
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└─────────СДВИГ──────────┘
РЕГИСТР ВЕРТИКАЛЬНОГО СКРОЛЛИНГА СЛОЙ 1
АДРЕС = 177246
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└─────────СДВИГ──────────┘
РЕГИСТР ВЕРТИКАЛЬНОГО СКРОЛЛИНГА СЛОЙ 0
АДРЕС = 177250
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└─────────СДВИГ──────────┘
РЕГИСТР ГОРИЗОНТАЛЬНОГО СКРОЛЛИНГА СЛОЙ 0
АДРЕС = 177252
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└───────СДВИГ─────────┘
РЕГИСТР ГОРИЗОНТАЛЬНОГО СКРОЛЛИНГА СЛОЙ 1
АДРЕС = 177252
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└───────СДВИГ─────────┘
РЕГИСТР ГОРИЗОНТАЛЬНОГО СКРОЛЛИНГА СЛОЙ 2
АДРЕС = 177252
ФОРМАТ РЕГИСТРА
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
└───────СДВИГ─────────┘
177230, далее пойдут биты с описанием
2;0 - режим цветовой интерпретации
4;3 - длина строки в словах
7;6 - растяжение по горизонтали - те количество повторов у точки
10;9 - количество повторов строк
11 - управление синхронизацией страниц =1 включена
15;12 - длина рулона в словах
теперь подробно
режим цветовой интерпретации, значение от 0 до 7
0 - 1 бит на цвет - 2 цвета
1 - 2 бита на цвет - 4 цвета
2 - 4 бита на цвет - 16 цветов
3 - 8 бит на цвет - 256 цветов
4 - 1 бит на цвет - 8 цветов - сборный "слоеный" режим
5 - 2 бита на цвет - 4 цвета - включены слои
6 - 4 бита на цвет - 16 цветов - включены слои
7 - 8 бит на цвет - 256 цветов - включены слои
пояснение к "слоеному" или "плановому" режиму 4
цвет формируется из 3х планов по 16кБ из которых считывается по 1 биту
номер цвета собирается так
старший бит [2] - из верхнего слоя (регистр 177232)
средний бит [1] - из среднего слоя (регистр 177240)
младший бит [0] - из нижнего слоя (регистр 177242)
данный режим интересен возможностью формировать текст читаемый сразу на VGA и на стандартном выходе
к примеру:
177232<-4 ая страница те 40000-77777 стандартный экран на БК11 и БК10
177240<-2000
177242<-2004
получается что если мы будем выводит основной текст по стандартному адресу 40000-77777
а цветовые аттрибуты в страницы 2000 и 2004 то у нас на VGA будет цветной текст
а на стандартном выходе - белый текст на черном фоне
этот подход удобен для создания универсального ПО с минимальными затратами
длина строки в словах
0 - 32 слова
1 - 64
2 - 128
3 - 256
это значение должно соответствовать вашему режиму - иначе будут повторы или пропуски данных
расчет прост - к примеру мы выбрали 512х384х16 цветов
считаем 512точек х 4 бита = 2048бит /16 = 128 слов
растяжение по горизонтали - те количество повторов у точки
0 - х1 - те 1024 точки в строке
1 - х2 - 512
2 - х3 - 256
3 - х4 - 128
количество повторов строк
0 - х1 - 768 строк
1 - х2 - 384
2 - х3 - 256
3 - х4 - 192
бит 11 - синхрониация отображаемых страниц, =1 включена
данный бит включает синхронизацию отображаемых страниц с отображением кадра
суть в том, что если мы к примеру поменяем значение в регистре 177232 - те установим новую отображаемую страницу, то при отключенной синхронизации, изменения будут приняты немедленно - вне зависимости от того что сейчас отображается на экране, а именно если сейчас идет отображение кадра то начиная со следующей строки будет отображаться новая страница.
если же явно включить синхронизацию =1 то страница поменяется только когда будет отображаться новый кадр. по-умолчанию синхронизация выключена.
длина рулона в словах
0 6144
1 8192
2 12288
3 16384
4 24576
5 32768
6 49152
7 65536
8 98304
9 131072
10 196608
11 262144
длина дает информацию контроллеру для корректной работы вертикального скролинга
и важный момент - длина рулона может быть БОЛЬШЕ чем экран
иначе говоря можно объявить экран в 32кБ (к примеру 256х256х16цветов )
а рулон выбрать в 64кБ, что позволит осуществлять формирование того что выйдет на экран ЗА его пределами ДО его вывода рулоном
типовые видеорежимы (значение восьмеричные)
012201 - 256х256х4цвета (экран 16кБ)
012100 - 512х256х2цвета (экран 16кБ)
032212 - 256х256х16цветов (экран 32кБ)
100010 - 1024x768x2цвета (экран 98кБ)
043223 - 256х192 256цветов (экран 48кБ)
052223 - 256х256 256цветов (экран 64кБ)
121133 - 512х384 256цветов (экран 192кБ)
регистр 177232 - адрес страницы начала отображения
те можно начинать отображение с любой страницы в памяти
для слоев добавлены регистры 177240 - средний слой под спрайты
и 177242 под фонобщее количество возможных сочетаний видеорежимов получается 60шт
Скроллинг через 177244-1772561. вертикальный скроллинг - построчный
2. горизонтальный скроллинг - пословный
иначе говоря это словное смещение
пояснения исходя из технической реализации1. строки читаются перед отображением в буфер длиной в 256 слов вне зависимости от длины строки заданной в регистре 177230
как следствие при превышении смещения получим отображение строки со смещением: к примеру если длина строки 32 слова (обычный режим БК), то смещение по горизонтали в 32 слова приведет к отображению со смещением на 1 строку вниз
2. большой размер строки может пригодится для работы в режиме отображения части плоскости:
к примеру мы объявляем плоскость 512х384 256 цветов (196кБ)
а отображаем только 256х192
соответственно окно отображения можно перемещать используя регистры скроллинга по горизонтали и по вертикали
Концепция работы слоев1. у нас три страницы с картинками
пусть первая - это нижний фон (адрес страницы 177242)
вторая - двигающиеся герои, факелы монстры и прочее (адрес страницы 177240)
третья - верхний фон (адрес 177232) который перекрывает объекты под ним - к пример колонна или дерево, за которое можно "зайти"
2. видеосистема складывает все три страницы
наивысший приоритет - верхний фон, те если там не =0 то идет перекрытие
далее вторая страница
и уже в самую последнюю очередь - нижний фон который перекрывает любой [не нулевого цвета] объект на странице выше
значение =0 это прозрачный цвет
3. слияние слоев работает в режимах от 4х цветов ибо в меньшем это просто лишено смысла
4. Для каждого слоя назначается своя палитра
4.1 для видеорежима с 2бит на цвет (пример 12205)
Верх - палитра 0
Середина - палитра 1
Низ - палитра 2
ну и так как палитры можно крутить, то можно назначить любой цвет в пределах 15ти бит
всего получается
В- 3й цвета (один прозрачный)
С- 3й цвета (один прозрачный)
Н- 4й цвета
итого 10 цветов, что круто ибо манипулировать-то надо всего 1й 16кБ страницей со спрайтами
в случае если будем делать мортал комбат - верхний фон можно пустить под одного героя
а середину под второго (ну а фон и останется фоном)
тогда решать задачу затирания спрайтов не придется совсем!
4.2 для 16ти цветных режимов тоже персональные палитры - но пул уже берем от типовой 256цветной палитры (см про палитры)
всего получается 15+15+16=46 цветов - КРУТО!
напомню формулу формирования цвета
цвет на выходе = VideoModeOffset + PaletteOffset + ColorIndex ;
VideoModeOffset - смещение видеорежима
cмещение - кол-во цветов (значения десятичные)
0 - 256
256- 4 х16
320- 16
336- 2
соответственно для 16ти цветов и слоев получаетяцвет на выходе = 0 + <номер слоя> + ColorIndex ;номер слоя:
верх -0
середина 1низ - 2
4.3 для 256цветов палитра очевидно едина ибо их хватит на все
4.4 режим монохрома в наложение не интересен, но тк код есть то я сделал его слоями
те В - старший бит ; С- cредний бит; H - младший бит цвета из 16ти цветной палитры
иначе говоря получился "плановый" видеорежим
к примеру код 12204 - это три страницы по 16кБ складываются в 8ми цветный 512х256 режим
Палитра - верхний кусок от 16ти цветной:
те сборному коду 0 соответствует 8код цвета
примеры:у нас установлен режим 4 цвета 256х256 (значение 12205 в регистре 177230 ) а палитра - пусть стандартная
итак верхняя страница задана в 177232
средняя в 177240
нижняя фоновая в 177242
читаем из верхней средней и нижней [далее В C Н] по два бита
В=11 - тк это не =0 то это перекрывающиее значение и оно идет на экран через трансляцию палитры
читаем дальше
B=00 - =0 значит фон прозрачный - надо идти дальше
С=00 - =0 и тут прозрачно - значит выводим то что на странице Н
Н=10 - код 10 идет на идет на экран через трансляцию палитры
читаем дальше
B=00 - =0 значит фон прозрачный - надо идти дальше
С=01 - !=0 дальше уже не идем и показваем спрайт из средней страниц
и код 01 идет на идет на экран через трансляцию палитры
читаем дальше
B=00 - =0 значит фон прозрачный - надо идти дальше
С=00 - =0 и тут прозрачно - значит выводим то что на странице Н
Н=00 - тк уже некуда просвечивать то этот код (00) идет на экран через трансляцию палитры
очевидно что коду 00 мы можем назначить любой из 32768 цветов равно как и другим кодам
Графическое пояснение как работают слои на примере режима 12205
Теперь о видеорежиме и его таймингахфизически AZБК вcегда формирует изображение в стандарте VGA в разрешении 1024х768 60Гц
Начиная с V15b4 в AZБК реализован режим РП (те часть экрана скрывается)
Начиная с V15b8 в AZБК реализовано управление синхронизацией отображаемых страниц
Автор: SuperMax 24.9.2023, 12:33
Блиттер (описание соответствует версии v15b9 и далее)
cм https://forum.maxiol.com/index.php?s=&showtopic=5553&view=findpost&p=58488
редакция от 2024-05-16
Блиттер в мой реализации есть робот читающий набор команд и выполняющих их по окончанию отображения кадра в отличии от классического блиттера в амиге, где команды подаются в режиме реального времени
https://forum.maxiol.com/index.php?s=&showtopic=5617&view=findpost&p=58282
изначальные ограничения:
1. блиттер оперирует только словами, иначе говоря минимальная дискретность по горизонтали - 2пикселя (в видеорежиме 256цветов) *все расчеты в блиттере ведутся словами.*
2.команда блиттера - 8 слов
3. блиттер может работать в автоматическом или ручном режиме запуска. автоматический режим запуска производится по факту окончания отображения видимой части кадра. ручной запуск производится по факту установки бита 12 в регистре управления блиттером (177270) и при установленном бите 14. Бит 14 доступен и по чтению и по записи, тогда как бит 12 будет всегда читаться как 0.
4. после получения сигнала к запуску блиттера, он сначала читает пакет команд в память ПЛИС, а зачем начинает выполнять пакет команд. как только блиттер начал что-то делать, блиттер устанавливает флаг своей работы (занятости) - бит 15 в регистре управления блиттером (177270), данный бит доступен по чтению, записать туда не получится. Для организации конвейерной обработки, есть бит 9 который устанавливается во время чтения пакета команд в буфер и означает запрет на изменения в этом пакете.
5. блиттер работает в плоском адресном пространстве со словами 16бит и адресом 24 бита
иначе говоря он видит всю память [расширенную - те 32МБ] сразу.
6. макс количество команд - 128.
8. макс количество слов в команде - те обрабатываемое в пакете - 256*256=65536 cлов
9. хранение исходных (SRC) спрайтов строго линейное и кратное 32м словам
те спрайт должен начинаться с адреса кратному 100(8)
9. расположение целевых данных (DST) прямоугольное - те строка cпрайта (ширина спрайта) + строчная инкрементация. важно для понимания: ширина спрайта + строчная инкрементация = длина строки в данном видеорежиме.
10. максимальная шbрина спрайта - 256 слов
11. максимальная строчная инкрементация - 256 слов
12. максимальное количество строк - 256
13. операции:
- заполнение константой
- копирование из SRC в DST (дискретность - слово)
- наложение SRC на DST и помещение результата в DST при SRC!=константа прозрачного цвета
(дискретность - байт)
- наложение SRC на DST и помещение результата в DST при SRC!=константа прозрачного цвета и DST==константа прозрачного цвета
(дискретность - байт)
- копиирование из прямоугольного DST в линейный SRC (сохранение фона)
(дискретность - слово)
- NOP - пропуск команды
что означает дискретность:
слово - те операция всегда пишет слово (2 байта)
байт - означает, что тут проверяется каждый байт на соответствие правил и пишутся только те байты которые выполнили условия
иначе говоря наложение спрайта на фон будет без дефектов - те оно попиксельное!
14. под блок команд блиттера выделяется страница (технически любая cвободная, просто команды читаются с начала указанной в регистре страницы)
иначе говоря набор команд можно быстро менять просто меняя номер страницы
15.После чтения строки команд в буфер ПЛИС, регистр номера страницы можно менять как угодно это сделано для того чтобы пока одна пачка команд выполняется, можно было подготовить новую пачку команд. для индикации есть бит 9 - он устанавливается во время чтения команд в буфер.данный бит доступен по чтению, записать туда не получится.при cброшеном бите 9 можно менять значение регистра количества команд на новое, однако если установить =0 как количество команд - блиттер асинхронно остановится.
во время своей работы блиттер устанавливает флаг - бит 15 в регистре управления блиттером (177270), данный бит доступен по чтению, записать туда не получится.
16. чтение пачки команд производится в память ПЛИС при выполнении условий:
автоматический режим: бит 14=0, количество команд не равно =0 и поступает флаг окончания отображения видимой части от VGA контроллера
ручной режим: бит 14=1, количество команд не равно =0 и затем установка бита 12 в регистре управления блиттером (177270)
17. процесс выполнения пачки команд не останавливается кроме как установкой количества команд в 0. если мы зафигачим 100 команд которые будут выполняться 5 кадров (к примеру) то чтение новой пачки не начнется пока вся пачка команд не выполнится. также изменения режимов ручной/автоматический или попытка ручного запуска будут проигнорированы!
18. правильный ручной запуск блиттера осуществляется так:
- устанавливаем ручной режим - те бит 14 (в регистре управления блиттером (177270))
- следующей командой (!) устанавливаем бит 12=1 (запуск) и количество команд
/данная технология необходима для исключения гонок внутри логики запуска блиттера/
допускается разбить на 3 этапа
- устанавливаем ручной режим - те бит 14 (в регистре управления блиттером (177270))
- устанавливаем количество команд
- устанавливаем бит 12=1 (запуск)
19. выполнение большого пакета команд блиттером:
- готовим пачку команд в страницу
- запускаем блиттер см п18
- ждем cброса флага занятости буфера бит 9=1 в регистре управления блиттером (177270)
(смысл в том что чтение пакета команд в память ПЛИС занимает некоторое время)
- устанавливаем в регистр номера страницы новую страницу с пачкой команд
- устанавливаем новое (не нулевое) количество команд в пакете
- ждем снятия флага работы блиттера бит 15=0 в регистре управления блиттером (177270)
- запускаем блиттер снова устанавливая бит 12=1 в регистре управления блиттером (177270)
20. для удобства работы с координатами добавлена явная координата Y в 7е слово, она ориентирована на видеорежим 256 слов в строке
базовый адрес формирует иначе говоря это часть базового адреса для удобства
addr_mem_dst<=addr_dst+{spr_Yadd,8'd0};
21. Команда 51 - предназначена для заливки константой по контуру спрайта, данный способ отметить пересечение или попадание было характерным для игр 80х годов
к примеру тут https://www.youtube.com/watch?v=LtetK6-x6bs&t=146s
герой засвечивается белым во время столкновения с шерифом
Управление блиттером осуществляется через два регистра
177270 - регистр управления, регистр сбрасывается в 0 по низкому B_HALT_L (системный сброс в БК)
177272 - номер страницы содержащей команды
запись 0 в 177270 вызывает полный асинхронный сброс/останов всех процессов блиттера
Код
РЕГИСТР УПРАВЛЕНИЯ БЛИТТЕРОМ
АДРЕС = 177270
ФОРМАТ РЕГИСТРА
доступен по чтению и записи
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │ │ │ │ │
│ │ │ │ ╔╧═════════════════════╧╗
│ │ │ │ ║ Количество команд R/W ║
│ │ │ │ ║ =0 выключен ║
│ │ │ │ ╚═══════════════════════╝
│ │ │ │ ╔═════════════════════════╗
│ │ │ └──╢ Флаг не трогать команду ║
│ │ │ ║ =1 R/O ║
│ │ │ ╚═════════════════════════╝
│ │ │ ╔══════════════════════════╗
│ │ └──────────╢ Ручной пуск блиттера W/O ║
│ │ ║ =1 пуск, по чтению =0 ║
│ │ ╚══════════════════════════╝
│ │ ╔══════════════════════════════════╗
│ └────────╢ Режим: Автоматический/Ручной R/W ║
│ ║ =1 ручной =0 пуск по концу кадра ║
│ ╚══════════════════════════════════╝
│ ╔════════════════════════════════════╗
└─────────╢ Блиттер выполняет пакет команд R/O ║
║ или читает пактет команд в буфер ║
║ =1 занят ║
╚════════════════════════════════════╝
РЕГИСТР СТРАНИЦЫ КОМАНД БЛИТТЕРА
АДРЕС = 177272
ФОРМАТ РЕГИСТРА
доступен по чтению и записи
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│15│14│13│12│11│10│09│08│07│06│05│04│03│02│01│00│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
│ │
╔╧════════════════════════════════════╧╗
║ Номер страницы с командами блиттера ║
╚══════════════════════════════════════╝
пояснение к флагам - бит
15 и
9 в
177270бит 15бит занятости блиттера - он установлен в =1 всегда когда блиттер занят чем-либо: читает команды в буфер или уже выполняет команды
бит 9 бит фиксации пачки команд, =1 означает, что блиттер читает пачку команд в буфер и сейчас ничего с командами делать ничего нельзя. данный бит предназначен для организации конвейерной обработки пакетов команд;
далее в описании рассматриваем видеорежим разрешение 512х384 256цветов, 196кБ экран, квадратный пиксель как основное
команда блиттера cодержит 8 слов1 словостарший байт - старшая часть адреса SRC
младший байт - старшая часть адреса DST
2 слово - младшая часть адреса SRC
3 слово - младшая часть адреса DST
4 слово - команда
биты
0 = 1 для команды нужно чтение SRC
1 = 1 для команды нужно чтение DST
2 = 1 флаг NOP - те наличие этого флага вызывает переход к следующей команде
3-4-5
номер команды
=0 заполнение константой CONST
=1 копирование SRC=>DST
=2 наложение SRC на DST =>DST при (при SRC!=прозрачный цвет SRC)
=3 наложение SRC на DST =>DST при (при SRC!=прозрачный цвет SRC) и (при DST=прозрачный цвет DST)
=4 копирование DST => SRC (сохранение фона)
=5 заполнение константой по контуру
в итоге получаются команды (в 8 системе)
= 0 заполнение константой
= 11 копирование SRC=>DST
= 21 наложение SRC на DST =>DST (при SRC!=прозрачный цвет SRC)
= 33 наложение SRC на DST =>DST (при SRC!=прозрачный цвет SRC) и (при DST=прозрачный цвет DST)
= 42 копирование DST=>SRC
= 51 заполнение константой по контуру
Пояснения - на примере команды заполнения константой: для нее не требуется установка битов чтения данных SRC или DST, тк запись данных (в данном случае константы идет безусловно). если мы поставим эти биты - ничего не произойдет для пользователя - лишь скорость выполнения команды уменьшится тк блиттер потратит время на чтение.
= 11 копирование SRC=>DST
тут чтобы положить данные в DST мы должны из считать из SRC - cоответственно проставляем бит чтения SRC, читать DST нам тут не надо тк нам пофиг - запись безусловная
= 21 наложение SRC на DST =>DST (при SRC!=прозрачный цвет SRC) тут аналогично - нужен только SRC для проверки условия
= 33 наложение SRC на DST =>DST (при SRC!=прозрачный цвет SRC) и (при DST=прозрачный цвет DST) - тут две проверки - и нам нужно считать и SRC и DST - соответственно установлены оба бита чтения зачем чтение вынесено в отдельные биты ? тупо оптимизация аппаратной части блиттера - экономия LC (бит проще проверять чем несколько битов)
= 51 наложение SRC на DST =>DST (при SRC!=прозрачный цвет SRC) тут аналогично - нужен только SRC для проверки условия
важно - константа заполнения в младшем байте, а константа прозрачного цвета SRC в старшем
(не как в 21й команде где константа прозрачного цвета SRC в младшем байте)
далее в примере будем рассматривать спрайт шириной 8 пикселей и высотой тоже 8 пикселей
количество слов получается (8/2)*8 = 32.
5 слово младший байтдлина спрайта в словах по горизонтали
иначе говоря в копировании 1в1 значение должно быть 1
(речь о копировании сплошного блока целиком)
а если спрайт по горизонтали 8. пикселей то указываем 3. тк копирование идет словами по 2 пикселя
старший байт количество строк
6 слово младший байт инкрементация адреса назначения после копирования строки спрайта
иначе говоря в копировании 1в1 значение должно быть 1
а если мы хотим вывести спрайт шриной 8. пикселей в строку длиной 256. слов
то мы должны указать инкрементацию - 256.-3.=253.
7 слово
Y координата для видеорежима 256. слов в строке
иначе говоря это часть базового 24х битного адреса для удобства
addr_mem_dst<=addr_dst+{spr_Yadd,8'd0};
8 слово младший байт - константа заполнения или константа прозрачного цвета SRC
старший байт - константа прозрачного цвета DST
команда 51 исключение:
младший байт - константа заполнения
старший байт - константа прозрачного цвета SRC
Для формирования команды можно использовать http://master.pdp-11.ru/blitter_calculator/blitter_command_calculator2.html
технология работы с блиттером - один из вариантовк примеру у нас на экране 5 спрайтов
соответственно в пакете команд - 10. команд с адресами спрайтов:
(первая команда - запись пустого поля, вторая запись спрайта)
каждый раз спрайты перерисовываются из памяти и копируются в средний слой
а для перемещения спрайта на новое место
1. чистим слой (к примеру средний) заполняя его прозрачным цветом те =0
2. пишем нижний спрайт
3. пишем верхний спрайт
.....
n. пишем самый верхний спрайт
иначе говоря порядок наложения спрайтов определяется порядком команд
Быстродействие блиттера:за время гашения кадра точно помещается пара команд со спрайтом 3.6-4кБ
соответственно для большего числа спрайтов рекомендуется буферизация
те один экран отображаем - другой рисуем и переключаем
соответственно вполне просто получить 60 кадров в секунду для плавности
FAQ:Q: А можно использовать блиттер для копирования информации ?
A: Да, можно ибо блиттер никак не отличает видеопамять от обычной памяти
Q: Видит ли блиттер память в самой БК
A: Нет, адресуется только память внутри AZБК
Q: А можно использовать блиттер для видеорежимов с 2-4-16 цветами ?
A: Технически никаких ограничений нет, просто все команды будут оперировать словами
и к примеру команды наложения (21 и 33 ) не будут выполнены корректно тк сравнение будет по байтам, но если подогнать данные до байтов то это прокатит