Я использую обе половинки. Одна - ОЗУ, вторая - квазидиск. Когда включается квазидиск, то старший бит kvazi_block становится 1 и включается половинка UB. Мне кажется, что проблема в самом алгоритме работы с квазидиском. Я видимо его неправильно понимаю. То что я выложил - одна из последних попыток. Изначально было так (и мне кажется это правильнее):
Код:
process (clk20, sync_cpu) -- эмуляция контроллера памяти КР580ВК38
begin
if (clk20'event and clk20 = '0' and sync_cpu = '1') then
db_status <= d_bus_O;
end if;
end process;
mem_rd <= '1' when (sync_cpu = '0' and db_status(7) = '1' and rd_en = '1' and wr_n = '1') else '0'; -- разрешение чтение из памяти
io_rd <= '1' when (sync_cpu = '0' and db_status(6) = '1' and rd_en = '1' and wr_n = '1') else '0'; -- разрешение чтение из порта
mem_wr <= '1' when (sync_cpu = '0' and db_status(1) = '0' and wr_n = '0' and rd_en = '0') else '0'; -- разрешение записи в память
io_wr <= '1' when (sync_cpu = '0' and db_status(4) = '1' and wr_n = '0' and rd_en = '0') else '0'; -- разрешение записи в порт
io_stack_rd <= '1' when (sync_cpu = '0' and db_status(2) = '1' and rd_en = '1' and wr_n = '1') else '0'; -- разрешение чтения из стэка (квазидиск)
io_stack_wr <= '1' when (sync_cpu = '0' and db_status(2) = '1' and wr_n = '0' and rd_en = '0') else '0'; -- разрешение записи в стэк (квазидиск)
..............
Здесь вырезан неинтересный блок распределения адресов. В нем же шина данных подается на SDRAM (d_bus_I <= SRAM_DQ(7 downto 0) when (mem_rd = '1' or io_stack_rd = '1'))
..............
SRAM_DQ(7 downto 0) <= d_bus_O when (ram_wr = '0' or io_stack_wr = '1') else "ZZZZZZZZ";
SRAM_WE_N <= ram_wr;
SRAM_CE_N <= '0';
SRAM_LB_N <= '0' when (kvazi_block(2) = '0' or (io_stack_wr = '0' and io_stack_rd = '0')) else '1';
SRAM_UB_N <= '0' when (kvazi_block(2) = '1' and (io_stack_wr = '1' or io_stack_rd = '1')) else '1';
SRAM_OE_N <= '0' when (ram_wr = '0' or io_stack_wr = '1' or io_stack_rd = '1' or mem_rd = '1') else '1';
SRAM_ADDR <= kvazi_block(1 downto 0) & a_bus when (kvazi_block(2) = '1' and (io_stack_wr = '1' or io_stack_rd = '1')) else "00" & a_bus;
process (clk20)
begin
if (clk20'event and clk20 = '0') then
if (io_wr = '1' and a_bus (15 downto 12) = "0100" and sync_cpu = '0') then
case d_bus_O(3 downto 0) is
when "1110" => kvazi_block <= "100";
when "1101" => kvazi_block <= "101";
when "1011" => kvazi_block <= "110";
when "0111" => kvazi_block <= "111";
when OTHERS => kvazi_block <= "000";
end case;
end if;
end if;
end process;
Т.е. мой алгоритм выглядит так:
1) Если производится запись в порт и адрес порта 40Н (0100 на старших 4-х битах шины адреса), то в зависимости от значения младших 4-х битов шины данных включается нужный блок квазидиска (см. код в case) путем присвоения значения сигналу kvazi_block. У этого сигнала старший бит используется для выбора половинки SRAM, а младшие два подставляются в адрес для SRAM (как 16-ый и 17-ый биты).
2) Далее при обращении к стеку (когда статусный бит 2 на шине данных при SYNC = 1 равен 1 активируется сигнал io_stack_wr или io_stack_rd) включается вторая половинка SRAM сигналом 0 на SRAM_UB_N, если квазидиск был включен (kvazi_block(2) = '1') записью в порт 40Н. Иначе 0 подается на LB (половинка ОЗУ).
В этом варианте при попытке выполнения команды SAVE выводится ошибка "NO SPACE". В варианте, который я приводил в предыдущем сообщении, диск работает и пишется без ошибок, но делается это в ОЗУ со всеми вытекающими последствиями, если пишется длинный файл (или много файлов). И команда STAT выдает при этом объем свободного пространства 51k.
Смущает, что в журнале было написано так: "Таким образом, при обращении к стеку и когда в порт 40Н записано 00, открывается электронный квазидиск. Если инициализация порта 40 не произведена, то стек формируется как обычно, в адресном пространстве основного ОЗУ."
По схеме же наоборот - если в порт записан 0 (значения старших 4-х битов не учитываются), то на все CAS блоков памяти квазидиска будут поданы нули и они все вместе включатся, что не есть хорошо.
Я делаю так, как я понял по схеме - ноль в нужном бите шины данных показывает какой блок включать.