User Tag List

Страница 7 из 30 ПерваяПервая ... 34567891011 ... ПоследняяПоследняя
Показано с 61 по 70 из 300

Тема: DivMMC

  1. #61

    Регистрация
    20.02.2005
    Адрес
    Новосибирск
    Сообщений
    941
    Спасибо Благодарностей отдано 
    808
    Спасибо Благодарностей получено 
    53
    Поблагодарили
    34 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от valerium Посмотреть сообщение
    Периодически возвращаюсь к своей плате nanoSD - пока результата нету.
    Уже и спек другой (тоже Ленин1, уже с корректировкой дешифрации клавиатуры и зарубленным кемпстоном), на разъеме а-ля ZXBUS вытащено все, что требуется divmmc - /NMI, подтянутый к единице, /ROMCS в ПЗУ выведен через диодное "ИЛИ" на ZXBUS 25B (подача единицы отрубает внутреннее ПЗУ). Но итог - "все те же на манеже".
    При запуске или сброс в бейсик48 с мигающим курсором сразу после Ltd (и не реагирует ни на клавиатуру, ни на NMI), или меняющийся мусор. А reset выполняется с моментальной перерисовкой белого экрана и заставки бейсика48, НО без очистки экрана и убирающихся полосок ! Через некоторое время это все может перейти в состояние с цветным мусором на экране и уже не сбрасываться в бейсик до выключения. Индикатор выбранной SD-карты может гореть, может не гореть - зависит от какой-то случайности.
    ПЗУ считывал и оно живое, в нем ESXDOS 0.8.8. Пайку ПЛИС и всех компонентов, насколько можно, проверил.
    Если вынуть ПЗУ из nanoSD (у меня в панельке) - должен ли отображаться матрас ? У меня вместо него мусор.

    Существует ли где-то описание логики работы divmmc ? С указанием портов, адресных окон, логики переключения страниц ОЗУ и перехвата обращений по точкам входа в обработчики ? (адреса последних я увидел в исходниках прошивки, но что там должно быть и как оно работает - не понял).
    Надо отлаживать как-то по частям, пока не пойму, как.

    Вот
    https://zx-pk.ru/threads/22237-vopro...l=1#post995850

    Скрытый текст

    Profi v5.03/1024k/палитра/FDD3,5""/FDD5,25"/HDD/XT-Keyb/Covox
    Pentagon-1024 sl v 1.4 upgrade #EFF7 Gluk RTC
    ZXM-Phoenix 1024k
    ATM Turbo 2+ v7.10 512k
    HIMAC HR42.04 48K
    HIMAC 128
    Ленинград 1
    [свернуть]

  2. #61
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #62

    Регистрация
    03.05.2020
    Адрес
    г. Челябинск
    Сообщений
    796
    Записей в дневнике
    3
    Спасибо Благодарностей отдано 
    260
    Спасибо Благодарностей получено 
    274
    Поблагодарили
    145 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от andykarpov Посмотреть сообщение
    Ну такое, так, да не совсем
    Я пробовал когда-то такой финт ушами, у меня не заработало
    Возможно что-то недоговаривают...
    Иначе все б давно уже перешли на автономные генераторы в DivMMC...
    Мне это тоже не совсем ясно, но вот кусок исходника CPLD.
    И это единственное место, где обрабатывается состояние clock. Здесь по спаду clock происходит либо смена состояния передачи (idle -> sample), либо чтение шины данных в регистр для передачи (состояне меняется sample -> transmit), либо выполняется один цикл из 16 обмена по SPI, в каждом нечетном из которых формируется один импульс spi_clock - чтение и запись бита. Больше clock ни к чему не привязан и синхронность с циклами CPU вроде как и не нужна.
    Код:
    -- spi transmission/reception
    
    	-- Update transmission state
    	process(clock, reset)
    	begin
    		if reset = '0' then
    			transState <= IDLE;
    			TState <= (others => '0');
    			fromSDByte <= (others => '1');
    			toSDByte <= (others => '1');
    			toCPUByte <= (others => '1');
    
    		elsif falling_edge(clock) then
    			case transState is
    			
    			when IDLE => -- Intercept a new transmission request (port 0x3F)
    				if address = zxmmc_spi_port and iorq='0' and m1='1' then -- If there is a transmission request, prepare to SAMPLE the databus
    					transState <= SAMPLE;
    				end if;
    			
    			when SAMPLE =>
    					if wr = '0' then -- If it is a SEND request, sample the CPU data bus
    						toSDByte <= D;
    					end if;
    					transState <= TRANSMIT; -- then start the transmission
    			
    			when TRANSMIT =>
    					TState <= TState + 1;
    
                 if TState < 15 then
    				 
    					if TState(0) = '1' then
    						toSDByte   <= toSDByte(6 downto 0)&'1';
    						fromSDByte <= fromSDByte(6 downto 0)& spi_datain;
    					end if;
                 else 
    				if TState = 15 then -- transmission is completed; intercept if there is a new transmission request
    						if address = zxmmc_spi_port and iorq='0' and m1='1'and wr='0' then							
    								toSDByte <= D;
    							   transState <= TRANSMIT;
    						else -- else we'll go in IDLE state.
    							transState <= IDLE;
    						--	TState <= "0000";
    						end if;
    						toCPUByte <= fromSDByte(6 downto 0)& spi_datain;
    					end if;
                 end if;
    			when OTHERS =>
    				null;
    			end case;
    		end if;
    		  -- SPI SD Card pins
    	SPI_clock <= TState(0);
    	spi_dataout <= toSDByte(7);
    	end process;
    Данные на шине данных тоже формируются только на основе /iorq, /rd и /m1 и тоже не зависят от тактовых импульсов проца:
    Код:
     D <= toCPUByte when (address = zxmmc_spi_port) and (iorq = '0') and (rd = '0') and m1='1' else "ZZZZZZZZ";
    Вот и вопрос: а зачем тут нужна синхронность с циклами CPU ?

    Не знаю как со стороны софта выполняется ожидание передачи байта по spi, но могу предположить, что там просто цепочка nop-ов в сумме на 16 тактов процессора. Тогда становится логичным, почему упомянутая частота генератора должна быть равна или НЕМНОГО выше процессорной - чтобы обмен прошел за это число тактов. И при автономном генераторе лучше, чтоб была выше (рассинхронизация обмена в пределах одного такта CPU не вызовет задержки обмена по spi).

    Поправьте меня, если несу пургу, но хочется хоть что-то в этом понять.

    - - - Updated - - -

    Цитата Сообщение от Djoni Посмотреть сообщение
    Аха, клево, значит конфигурация памяти в DivIDE рулится в основном через порт управления #E3. В нижних таблицах показаны значения маппирования ROM (0000-1FFF) и банков RAM (#0000-1FFF и #2000-3FFF) и показаны точки входа маппирования RAM для перехвата ряда адресов (reset, nmi, int im2, trdos и неких процедур load и save).
    И наверное в DivMMC оно все так же, коли все работает с одним и тем же esxdos.

    Эт чо получается, там из огромной озухи используется всего четыре страницы по 8К ?? Я думал, что bank(3 downto 0) - это четырехразрядный номер банка, а оказывается работают только bank0-bank3 и это просто прямые сигналы выбора одного из 4 банков ?

    В DivMMC номер банка 6-разрядный и вроде как в него пишется действительно номер страницы, но еще надо искать, сколько этих страниц адресуется реальным ПО
    Код:
    		elsif	rising_edge(divideio) then
    		
    			bank(5 downto 0) <= D(5 downto 0);
    			mapram           <= D(6) or mapram;
    		   conmem          <= D(7);
    		end if;
    А вот то, что вверху таблицы, относится только к управлению ATA-устройством и для SD неприменимо.

  4. #63

    Регистрация
    03.05.2020
    Адрес
    г. Челябинск
    Сообщений
    796
    Записей в дневнике
    3
    Спасибо Благодарностей отдано 
    260
    Спасибо Благодарностей получено 
    274
    Поблагодарили
    145 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Собственно, вот тут немного подробностей по divmmc в разделе "Some techtalk". Возможно не скажу ничего нового, но для меня это было находкой: DivMMC - это гибрид из 1) DivIDE в части маппирования 8К-страниц памяти ROM+RAM и управления ей через регистр конфигурации (порт #E3) и из 2) ZXMMC в части обмена с картой памяти по SPI. Только здесь для SPI используются порты #E7 (zxmmc_control_port) и #EB (zxmmc_spi_port) вместо #1F и #3F соответственно.
    В итоге мы имеем два почти независимых устройства и первое всего слегка сложнее порта конфигурации #7FFD, причем ему не нужен clock. ПЗУ должно мапиться в нижние 8К сразу после reset-а.
    Но на Ленине этого не происходит ((

    Конфликтовать divmmc на ленинграде может разве что с портом кемпстон-джойстика - все три адреса портов divmmc имеют A0=1 и в исходном Ленине при чтении любого из портов #E3, #E7, #EB отзовется кемпстон. У меня кемпстон зарублен (/CS мультиплексоров выбирается только при A0=0) и соот-но конфликта нет. Но и не в этом причина.

    У меня есть DivIDE 5.7C, который точно работал на Арлекине. При подключении его к Ленину я тоже вижу МАТРАС. То есть при сбросе у него /ROMCS правильно встает в единицу, отключает штатное ПЗУ, но он не включает свое. Есть идеи, почему ?
    Последний раз редактировалось valerium; 11.09.2020 в 23:56.

  5. #64

    Регистрация
    27.02.2005
    Адрес
    москва
    Сообщений
    14,291
    Записей в дневнике
    1
    Спасибо Благодарностей отдано 
    202
    Спасибо Благодарностей получено 
    1,456
    Поблагодарили
    946 сообщений
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от valerium Посмотреть сообщение
    Есть идеи, почему ?
    а что с дешифрацией портов ?
    в оригинале (на плате ленина) всего два порта - все чётные и нечётные

  6. #65

    Регистрация
    03.05.2020
    Адрес
    г. Челябинск
    Сообщений
    796
    Записей в дневнике
    3
    Спасибо Благодарностей отдано 
    260
    Спасибо Благодарностей получено 
    274
    Поблагодарили
    145 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от goodboy Посмотреть сообщение
    а что с дешифрацией портов ?
    в оригинале (на плате ленина) всего два порта - все чётные и нечётные
    Во всем Ленине из читаемых портов - только клавиатура, кемпстон и tape in.
    Из записываемых - только #FE (бордюр, спикер, tape out).
    Записываемые у меня поправлены для неконфликта с AY по A0=0 и они нам сейчас неинтересны, т.к. у divmmc все три порта имеют A0=1 и в #FE никак не попадут.
    В читаемых портах клавиатура и tape in - это все #xxFE (A0=0), с divmmc не пересекаются.
    А вот кемпстон при A0=1 мог пересекаться, но это тоже исправлено - мультиплексоры клавы/кемспстона сейчас отзываются только на клаву (A0=0).
    Вот схема проделанного безобразия:
    https://yadi.sk/i/qwYbOS9jkC15Og

  7. #66

    Регистрация
    20.11.2017
    Адрес
    г. Ростов-на-Дону
    Сообщений
    352
    Спасибо Благодарностей отдано 
    30
    Спасибо Благодарностей получено 
    88
    Поблагодарили
    50 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Пытаюсь понять как работает 'маппер' в DivIDE/DivMMC. Эскпериментирую в emu, а там, глядишь и в реале, на рассыпухе, есть желание его сделать.
    Если представить карту памяти, то получается 8 вариантов.
    Два бита из регистра управления Е3h, CONMEM-бит_7 и MAPRAM-бит_6 и бит, назову его trap - активация пеключения при попадании в определенные адреса.
    если судить из этого описания DivIDE:
    --------------------------------------------------------------------------------------------------------------------
    So, when CONMEM is set, there is:
    0000-1fffh - EEPROM/EPROM/NOTHING(if empty socket), and this area is flash-writable if EPROM jumper is open.
    2000-3fffh - 8k bank, selected by BANK 0..1 bits, always writable.

    When MAPRAM is set, but CONMEM is zero, and entrypoint was reached:
    0000-1fffh - Bank No.3, read-only
    2000-3fffh - 8k bank, selected by BANK 0..1. If it's different from Bank No.3, it's writable.

    When MAPRAM is zero, CONMEM is zero, EPROM jumper is closed and entrypoint was reached:
    0000-1fffh - EEPROM/EPROM/NOTHING(if empty socket, so open jumper in this case), read-only.
    2000-3fffh - 8k bank, selected by BANK 0..1, always writable.

    Otherwise, there's normal speccy memory layout. No modified ROM, no shit.
    --------------------------------------------------------------------------------------------------------------------
    вариант 1) получается, что при CONMEM==1 не имеет значение состояние бит MAPRAM и trap, всегда будет 'DivROM' и некая страница 'DivRAM'
    при CONMEM==0 получаем:
    вариант 2) MAPRAM==1, trap==1, когда первые 8КБ, это третья страница 'DivRAM' только чтение, а вторые 8КБ, это некая страница 'DivRAM'
    вариант 3) MAPRAM==0, trap==1, повторяем вариант 1)
    вариант 4-8) все остальные варианты, это обычное ПЗУ ZX48.

    итого:
    если CONMEM==0, MAPRAM==0, trap==0 карта=0, вариант 4)
    0000-3fffh 16k normal speccy EEPROM memory layout

    если CONMEM==0, MAPRAM==0, trap==1 карта=1, вариант 3)
    0000-1fffh - EEPROM/EPROM/NOTHING(if empty socket, so open jumper in this case), read-only.
    2000-3fffh - 8k bank, selected by BANK 0..1, always writable.

    если CONMEM==0, MAPRAM==1, trap==0 карта=2, вариант 4)
    0000-3fffh 16k normal speccy EEPROM memory layout

    если CONMEM==0, MAPRAM==1, trap==1 карта=3, вариант 2)
    0000-1fffh - Bank No.3, read-only
    2000-3fffh - 8k bank, selected by BANK 0..1. If it's different from Bank No.3, it's writable.

    если CONMEM==1, MAPRAM==0, trap==0 карта=4, вариант 1)
    если CONMEM==1, MAPRAM==0, trap==1 карта=5
    если CONMEM==1, MAPRAM==1, trap==0 карта=6
    если CONMEM==1, MAPRAM==1, trap==1 карта=7
    0000-1fffh - EEPROM/EPROM/NOTHING(if empty socket), and this area is flash-writable if EPROM jumper is open.
    2000-3fffh - 8k bank, selected by BANK 0..1 bits, always writable.
    --------------------------------------------------------------------------------------------------------------------
    вот так я дополняю конфигурацию в emu ZX_Spectrum_48:

    Скрытый текст

    cpu : z80 {
    debug=cas
    debug=trap
    mem=mm
    int[FF]=vid.irq
    port[a3]=hdd.data8[0]
    port[a7]=hdd.data8[1]
    port[ab]=hdd.data8[2]
    port[af]=hdd.data8[3]
    port[b3]=hdd.data8[4]
    port[b7]=hdd.data8[5]
    port[bb]=hdd.data8[6]
    port[bf]=hdd.data8[7]
    port[E3]=portE3
    port[E7]=sdcard.ss
    port[EB]=sdcard.data8
    port[FD]=portFD
    port[FE]=sys.data[0]
    }

    biosESX : Memory {
    rom="ZX\esxmmc.bin"
    }

    mem2 : Memory {
    size=20000
    frame[0].size=2000
    frame[0].page=portE3.portA[0-3]
    }

    mem2p : MemMap {
    page[3]=portE3.portA[3]
    page[2]=portE3.portA[2]
    page[1]=portE3.portA[1]
    page[0]=portE3.portA[0]

    map[15][0000-1FFF]=mem2[1e000]
    map[14][0000-1FFF]=mem2[1c000]
    map[13][0000-1FFF]=mem2[1a000]
    map[12][0000-1FFF]=mem2[18000]
    map[11][0000-1FFF]=mem2[16000]
    map[10][0000-1FFF]=mem2[14000]
    map[9][0000-1FFF]=mem2[12000]
    map[8][0000-1FFF]=mem2[10000]
    map[7][0000-1FFF]=mem2[e000]
    map[6][0000-1FFF]=mem2[c000]
    map[5][0000-1FFF]=mem2[a000]
    map[4][0000-1FFF]=mem2[8000]
    map[3][0000-1FFF].ro=mem2[6000]
    map[2][0000-1FFF]=mem2[4000]
    map[1][0000-1FFF]=mem2[2000]
    map[0][0000-1FFF]=mem2[0000]
    }

    mm : MemMap {
    page[2]=portE3.portA[7]
    page[1]=portE3.portA[6]
    page[0]=trap.output

    map[0][0000-3FFF]=bios[0000]
    map[0][4000-FFFF]=mem1[0000]

    map[1][0000-1FFF]=biosESX[0000]
    map[1][2000-3FFF]=mem2.frame[0]
    map[1][4000-FFFF]=mem1[0000]

    map[2][0000-3FFF]=bios[0000]
    map[2][4000-FFFF]=mem1[0000]

    map[4][0000-1FFF]=biosESX[0000]
    map[4][2000-3FFF]=mem2.frame[0]
    map[4][4000-FFFF]=mem1[0000]

    map[5][0000-1FFF]=biosESX[0000]
    map[5][2000-3FFF]=mem2.frame[0]
    map[5][4000-FFFF]=mem1[0000]

    map[3][0000-1FFF].ro=mem2[6000]
    map[3][2000-3FFF]=mem2p
    map[3][4000-FFFF]=mem1[0000]

    map[6][0000-1FFF]=biosESX[0000]
    map[6][2000-3FFF]=mem2.frame[0]
    map[6][4000-FFFF]=mem1[0000]

    map[7][0000-1FFF]=biosESX[0000]
    map[7][2000-3FFF]=mem2.frame[0]
    map[7][4000-FFFF]=mem1[0000]

    initpage=0
    }

    portE3 : K580ww55 {
    }

    trap : exec-sensor {
    range[0000-0001]=1
    range[0008-0009]=1
    range[0038-0039]=1
    range[0066-0067]=1
    range[04c6-04c7]=1
    range[0562-0563]=1
    range[3D00-3DFF]=1
    range[1FF8-1FFF]=0
    }

    sdcard : sd-mmc {
    image="zx\SanF2.raw"
    }

    hdd : cf-ide {
    drive[0].image="zx\SanF2.raw"
    drive[0].geometry=1024C16H63S
    ; ca a (cat a)
    }
    [свернуть]


    но ничего не работает.
    Переключение DivROM и страниц DivRAM в отладчике видно, но при попытке из DivROM вывести текст приглашения, идет вызов функции ПЗУ ZX48, там далее, вызов на rst 8, его перехват(trap) на DivROM, а вот обратно возврат происходит в пустую страницу DivRAM 0х2246...
    Получается, что то не так с распределением страниц, где ошибка, может кто подсказать?
    Последний раз редактировалось PVV; 03.10.2020 в 00:05. Причина: добавил секцию в trap 0038-0039 и порты IDE

    Этот пользователь поблагодарил PVV за это полезное сообщение:

    valerium(03.10.2020)

  8. #67

    Регистрация
    20.11.2017
    Адрес
    г. Ростов-на-Дону
    Сообщений
    352
    Спасибо Благодарностей отдано 
    30
    Спасибо Благодарностей получено 
    88
    Поблагодарили
    50 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Нашел пару ошибок в конфигурации, исправил сообщение выше, теперь fatware и tbios находят мастер ide диск, а вот ESXdos никаких признаков жизни не подает.
    Смущает в описании DivIDE, что записав один раз бит MAPRAM, можно его уже не указывать при установке страниц, а карта памяти будет как при установленном бите. В конфигурации выше это не учитывается, так ли это обязательно, и, вообще, правильно ли я это понимаю?

  9. #68

    Регистрация
    20.11.2017
    Адрес
    г. Ростов-на-Дону
    Сообщений
    352
    Спасибо Благодарностей отдано 
    30
    Спасибо Благодарностей получено 
    88
    Поблагодарили
    50 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Не пойму способ переключения к основной ПЗУ ZX:
    The one-instruction delay can be used to distinguish between nested calls to
    the same place. To do this you should place different instructions at the
    entry point address than is in the original ROM. The first call will execute
    the original instruction, but any subsequent call will execute the
    instruction in the paged-in memory.

    Задержка в одну инструкцию может использоваться, чтобы различать вложенные вызовы
    в одно и то же место. Для этого вы должны разместить другие инструкции на
    адрес в основном ПЗУ. Первым вызовом будет выполнена
    исходная инструкция, но любой последующий вызов выполнит
    инструкцию в DivRAM странице памяти.
    This is particularly useful for avoiding nested NMI calls, which can not be
    easily implemented using hardware. It also allows the divIDE to use INTs for
    timing. When divIDE code is excuted, external calls will map divIDE out and
    continue at the original code at 0038h, but nested INTs can jump to
    different code.

    Это особенно полезно для обработки вложенных вызовов NMI, которые не могут быть
    легко реализуемы аппаратно. Это также позволяет divIDE использовать прерывания INT для
    учета времени. Когда выполняется код divIDE, внешние вызовы отключат divIDE и
    продолжат исполнение исходного кода с 0038h, но вложенные прерывания INT перейдут к выполнению
    другого кода.
    что это значит, может кто это прояснить?
    существует некая задержка в одну инструкцию на переключение? эта задержка актуальна только на возврат к основной ПЗУ? сама возможность такой задержки на одну инструкцию триггерная?
    как то я совсем запутался...

  10. #69

    Регистрация
    03.05.2020
    Адрес
    г. Челябинск
    Сообщений
    796
    Записей в дневнике
    3
    Спасибо Благодарностей отдано 
    260
    Спасибо Благодарностей получено 
    274
    Поблагодарили
    145 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Несколько раз прочитал и тоже не пойму, почему это one instruction delay. Может это плохой перевод с испанского/польского/еще какого-то неведомого языка ? Задержка-то не на одну инструкцию, а на один вход в адрес - скорее, 'one call delay'. Исключает вложенные вызовы nmi-обработчика из самого же себя. Первый вызов, например, на 0038h выполняет код оригинального ПЗУ, второй вызов по этому же адресу мапит какую-то из страниц divide и выполняет переход на код, который находится в ней.
    Также позволяет использовать INT для тайминга в divIDE- первый вызов по INT-у отключит пзу divIDE и выполнит оригинальный обработчик основного пзу, второй же вызов к этому адресу уже будет выполнять код из пзу divIDE (вот тут я не пониамаю, что будет с третьим и последующими).
    А где можно почитать сей доблестный документ ? Я одно время очень искал, но так и не нашел описания логики для divIDE/mmc.
    Последний раз редактировалось valerium; 08.10.2020 в 05:47.

  11. #70

    Регистрация
    20.11.2017
    Адрес
    г. Ростов-на-Дону
    Сообщений
    352
    Спасибо Благодарностей отдано 
    30
    Спасибо Благодарностей получено 
    88
    Поблагодарили
    50 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Сам документ найти не проблема, на этой страничке в разделе technical documentation - divIDE programming model, это будет версия 1.03, а в архиве, в разделе download - FATware 0.14a, версия 1.04 (сравнил их построчно, отличий, по сути, нет).
    есть у меня еще, вероятно одно из первых описаний:

    Скрытый текст

    DivIDE programming model
    ------------------------

    DivIDE interacts with ZX Spectrum using I/O accesses or automatically by
    replacing original ZX-ROM with its own memory, when CPU fetch from an
    entry-point is detected (and such behavior is somehow allowed).

    DivIDE contains 8 kB ROM (could be not present, EPROM or EEPROM, in the third
    case it's in-system reprogrammable) and 32-512 kB RAM. DivIDE can use system
    from 3rd 8k bank of its RAM, this is suitable especially for safe system
    development. Accidental EEPROM damage (due to unlucky out from crashed code)
    is fused by the on-board jumper.

    All ports are decoded using A0..A7 address-wires only. So you can access all
    eight IDE-registers from so caled command block (rrr=0..7) at addresses
    xxxx xxxx 101r rr11. Other divIDE features are controlled using dedicated
    port at address xxxx xxxx 1110 0011, which belongs to divIDE CONTROL REGISTER.


    IDE command block registers
    ---------------------------

    [ DATA REGISTER (R/W) ]
    xxxx xxxx 1010 0011, 0a3h, 163

    This register serves for reading or writing sectors. It's 16-bit wide, so
    divIDE is joining write-pairs into words and splitting readed words into bytes.

    When reading from this register, each ODD access will return low byte of
    readed word (while high byte is stored into latch and buffer pointer is shifted
    to next word). Each EVEN access will return that high byte, stored in previous
    read access to DATA REGISTER.

    When writing to DATA REGISTER, each ODD access will store the byte into latch.
    Each EVEN access will join the previously stored low portion with actual byte
    (considered to be high portion), and this word is written into harddrive (and
    next word in harddrive buffer is pointed).

    After any access to non-data command block registers (rrr=1..7) or to divIDE
    control register, following DATA REGISTER access is considered to be ODD.
    Accesses outside divIDE ports cannot change the EVEN/ODD state. After reset or
    power-on, this state is unknown.


    [ ERROR REGISTER (R) / FEATURES REGISTER (W) ]
    xxxx xxxx 1010 0111, 0a7h, 167

    [ SECTOR COUNT REGISTER (R/W) ]
    xxxx xxxx 1010 1011, 0abh, 171

    [ SECTOR NUMBER REGISTER (R/W) (too LBA bits 0..7) ]
    xxxx xxxx 1010 1111, 0afh, 175

    [ CYLINDER LOW REGISTER (R/W) (too LBA bits 8..15) ]
    xxxx xxxx 1011 0011, 0b3h, 179

    [ CYLINDER HIGH REGISTER (R/W) (too LBA bits 16..23) ]
    xxxx xxxx 1011 0111, 0b7h, 183

    [ DRIVE/HEAD REGISTER (R/W) (too LBA bits 24..28) ]
    xxxx xxxx 1011 1011, 0bbh, 187

    [ STATUS REGISTER (R) / COMMAND REGISTER (W) ]
    xxxx xxxx 1011 1111, 0bfh, 191


    For detailed desription of mentioned registers have a look at
    http://www.t13.org .


    DivIDE control register
    -----------------------

    [ CONTROL REGISTER (Write Only) ]
    xxxx xxxx 1110 0011, 0e3h, 227

    This register is write-only (readed data will be unknown). All bits are reset to
    '0' after each power-on. Unimplemented bits, marked 'X', should be zeroed for
    future compatibility issues with more than 32kB RAM DivIDEs.

    7 6 5 4 3 2 1 0
    [ CONMEM , MAPRAM, X, X, X, X, BANK1, BANK0 ]

    Bits BANK1 and BANK0 select the 8k bank, which normally appears in area
    2000-3fffh, when divide memory is mapped.

    Bit MAPRAM can be set to '1' only (when it's '1', only power-on can return it
    to '0'). This bit allows 8k bank No.3 to act as EPROM/EEPROM, and write-protects
    it. Set it when system image is loaded into bank No.3 and you want to safe probe
    it till the next power-on. Set it also when you haven't EPROM/EEPROM, and you
    want to use system. (Because u will possibly re-install it from MAPRAM mode, you
    will need CONMEM to override writeprotect. Because after returning to BASIC you
    rely on original ROM, you must reset automapper, which could be left in
    undesired state by previous bus transactions. Because it could be done only by
    fetching code from off-area, u must set DI, then call 1ffbh ('RET'), ten CONMEM, loading image,
    releasing CONMEM and setting MAPRAM, then EI. Then the return is safe.)


    Bit CONMEM forces EPROM/EEPROM to 0000-1fffh and by BANK 1..0 selected bank to
    area 2000-3fffh, regardless to the actual divIDE state or to physical presence
    of EPROM/EEPROM. Bank in area 2000-3fffh is always writable, and in 0000-1fffh
    always appears EEPROM/EPROM, which is writable when EPROM jumper is open. Use
    it in third-party utilities for loading system or modules, or in system's
    auto-upgrade process.


    Memory mapping
    --------------

    Memory mapping could be invoked manually (by setting CONMEM), or automatically
    (CPU has fetched opcode form an entry-point). Automatic mapping is active
    only if EPROM/EEPROM is present (jumper EPROM is closed) or bit MAPRAM is set.
    Automatic mapping occurs at the begining of refresh cycle after fetching
    opcodes (M1 cycle) from 0000h, 0008h, 0038h, 0066h, 04c6h and 0562h. It's
    also mapped instantly (100ns after /MREQ of that fetch is falling down) after
    executing opcode from area 3d00..3dffh. Memory is automatically disconnected in
    refresh cycle of the instruction fetch from so called off-area, which is
    1ff8-1fffh.

    The one-instruction delay could be used to distinguish between nested calls to
    the same place. For such trick you will place different instruction at the
    entrypoint address, than is in original ZX ROM. So the first call wil execute
    original instruction, but subsequent one will jump to another code, because
    divIDE memory was already mapped, with its changed opcode. It's great for 100%
    avoidance of nested NMI, which cannot be implemented using pure combinatorial
    hardware workaround. It allows divIDE to use INT for timing, when divIDE code is
    performed (external calls will map later divIDE off and continue in #38h
    original service, but nested INTs can jump to another work, and mapping off is
    of course undesirable there).

    In automatic mapping, when MAPRAM is set, in location 0000h-1fffh appears
    write-protected Bank No.3, instead of EEPROM/EPROM. The meaning-priority is
    (from lowest to highest) EPROM jumper -> MAPRAM -> CONMEM. So because that
    jumper is no more significant when MAPRAM or even CONMEM is set, it's used
    to distinguish between fused or unfused EEPROM state for CONMEM mode.

    So, when CONMEM is set, there is:
    0000-1fffh - EEPROM/EPROM/NOTHING(if empty socket), and this area is
    flash-writable if EPROM jumper is open.
    2000-3fffh - 8k bank, selected by BANK 0..1 bits, always writable.

    When MAPRAM is set, but CONMEM is zero, and entrypoint was reached:
    0000-1fffh - Bank No.3, read-only
    2000-3fffh - 8k bank, selected by BANK 0..1. If it's different from Bank No.3,
    it's writable.

    When MAPRAM is zero, CONMEM is zero, EPROM jumper is closed and entrypoint was
    reached:
    0000-1fffh - EEPROM/EPROM/NOTHING(if empty socket, so open jumper in this case),
    read-only.
    2000-3fffh - 8k bank, selected by BANK 0..1, always writable.

    Otherwise, there's normal speccy memory layout. No modified ROM, no shit.

    And, that's all, Folks! Do you think, it's too complex? Read it once again.
    Do you still think, it's not sane? Feel free to ask me (Zilog), my email is
    xcimbal@quick.cz. I hope you will enjoy this piece of hardware, i have spent
    months for optimising this marvelous piece of shit.

    With regards
    Zilog
    [свернуть]

    опять же, это сути текущего вопроса не раскрывает.
    Казательно вызовов, на мой взгляд, тут именно речь идет об одной инструкции, а не всем обработчике.
    Возможно, если мы находимся в DivROM, и вызываем код самой же DivROM, то вызов идет без задержки, а если же код исполняется в основной ROM и идет вызов на адрес, где должен сработать trap, то первая инструкция выбирается из основной ROM, а вторая из подмененой страницы DivROM/RAM.
    Смотрю исходники fuse-1.5.7, как там организовано переключение, но не вижу ни каких 'хитростей'.

Страница 7 из 30 ПерваяПервая ... 34567891011 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. basic128 и DIVMMC EsxDos
    от azx987sa в разделе Внешние накопители
    Ответов: 6
    Последнее: 08.05.2020, 00:18
  2. Ленинград 1 (48К) и Brand new DivMMC EnJOY
    от FSound в разделе Ленинград
    Ответов: 1
    Последнее: 16.12.2016, 15:51

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •