Просмотр полной версии : Передача параметров хитрой железке
Граждане программеры, возник вопрос: щас прорабатывается концепция хитрой железки, и вот возникла необходимость железяке передавать команды и параметры, железяка достаточно умная теоретически умеет прослушивать шину спекка и соответствующим образом реагировать. В общем нужна помощь искушонных в Z80 людей.
Так как планируется свести к минимуму колво портов в адресном пространстве машинки мы добавляем всего 2 порта 1-индекс внутреннего регистра, 2 непосредственно адресуемый регистр в связи с этим становиться неудобно передавать параметры,
так как получается следующего вида манипуляции
1. устанавливаем в первом порту номер регистра для параметра 1
2. записываем параметр в порт 2
и так для каждого регистра. плюс ситуация усугубляется еще и тем что параметры очень часто первышають 8 бит (то есть могут встречаться 2 байтные параметры)
Была одна из мыслей реализовать следующим образом передачу параметров.
ld h,код команды
ld l, первый 1 байтый параметр
push hl // записываем в стек
ld hl,параметр2
push hl
ld hl,параметр3
push hl
ld hl,параметр4
push hl
ld a,a // признак железяке что необходимо исполнить команду
// возвращаем стек в нормальное состояние
pop hl
pop hl
pop hl
pop hl
Железяка ведет себя следующим образом, у нее есть FIFO буфер длинной в 8 байт, железяка прослушивает шину и видет что процу попалась команда PUSH HL после чего следует 2 цикла записи в память - железка пихает их в FIFO буфер
Далее если процу попадается команда ld a,a она это дело воспринимает как признак для исполнения команды (код команды получается лежит в FIFO как самый старый байт). То есть метод как бы позволяет без проблем передавать 16 бит параметры и команды, но у него есть существенные недостатки
1. Юзается стек
2. если между инструкциями PUSH HL происходит прерыание и в обработчике прерываний тоже встречаются команды PUSH HL то естественно железяка засунет эти байты в FIFO очередь (то есть уже совсем левые параметры)
3. Нужно стек возвращать в исходное состояние - а это лишние траты тактов проца
В общем это я привел один из примеров что бы было видно что можно достаточно нетривиально поступать.
Основные требования к методу это
1. Скорость работы
2. возможность удобно передавать 2 байтные параметры (хоят тут выменя можете разубедить что вы 2 байтные параметры можете пердавать и байтику и вам это не мешает)
3. предусмотреть возможность что количество параметров может быть непостоянно
И еще так как тема относиться вроде бы к железяке добавлю что железяку тут не обсужаю, важно мнение программистов которые теоретически будут работать с данным делом и важна оптимальность взаимоотношения железяки и программаного обеспечения
Можно сделать так: 2 порта регистр команд/состояния и регистр данных. Шлем команду "записать данные в регистр N", протом шлем необходимое количество байт в рег данных. Чтение аналогично. 256 команд надеюсь хватит ;)
классические порты незачем бояться :) или расшаренная память как самый быстрый вариант кидания массивов.
Шлем команду "записать данные в регистр N", протом шлем необходимое количество байт в рег данных.
так и работает v9990 между прочим - указываешь стартовый адрес, и пошел пхать байты подряд :)))) OUTI не слишком тормознее стекового копирования, вполне сносно. и достаточно просто чтобы юзать.
OUTI не слишком тормознее стекового копирования
Тут вот в чем вопрос допустим тебе штук 10 одинаковых команд послать надо они только отличаются скажем одним параметром, а параметр в цикле вычисляется получаются такие телодвижения
Для начала выделяем где нить буфер для комадного пакета
заполняем его
при помощи outi запихиваем в железяку
вычисляем параметр
правим буфер
и все сначала
Тоесть есть лишние телодвижения, вопрос - как вы считаете это нормально (можно ли с этим смириться)?
captain cobalt
12.07.2006, 17:29
планируется свести к минимуму колво портов в адресном пространстве машинки Альтернативный вариант - открывающиеся/закрывающиеся порты.
Когда работает старый софт, который может нагадить в порты, порты закрыты и не реагируют.
Новый крутой софт работает при открытых портах и использует их возможности.
1. Юзается стек Можно прослушивать только команду LD и брать её непосредственные операнды.
Код будет выглядеть так:
LD HL,#xxxx
LD HL,#yyyy
LD HL,#zzzz
LD A,A
Другой вариант - DMA.
2. если между инструкциями PUSH HL происходит прерыание Умная железка могла бы прослушивать их и вести себя соответственно.
Можно прослушивать только команду LD и брать её непосредственные операнды.
Код будет выглядеть так:
Думали над таким вариантом, трабл в том что если в цикле смыкать такую конструкцию, то прийдется делать самомодифицируищейса код, да и результат вроде медленней получается чем при использовании outi (хотя таблички под рукой нет мог и соврать).
Склоняюсь наверное к варианту работы с блочными командами ввода вывода у нее 2 плюса
1. не надо будет сильно извращаться
2. реализация железяки проще будет
ут вот в чем вопрос допустим тебе штук 10 одинаковых команд послать надо они только отличаются скажем одним параметром, а параметр в цикле вычисляется получаются такие телодвижения
Для начала выделяем где нить буфер для комадного пакета
заполняем его
при помощи outi запихиваем в железяку
вычисляем параметр
правим буфер
и все сначала
а как этот самый параметр у тебя планируется править когда он уже залитый в FIFO буфере лежит :)
ну и кучка pop hl - тоже время как бы кушает-то :)
а можно не ипать мозги а повесить 256 байт обычного озу на старший байт (a8-15) порта и править эти команды хоть вдоль хоть поперек.
Нечетко выразился
Просто ты можеш в регистре нужные манипуляции провести и послать заново push hl. В общем варант с outi все самый оптимальный выходит.
а мне память на портах больше нравица ;)
Так как планируется свести к минимуму колво портов в адресном пространстве машинки мы добавляем всего 2 порта 1-индекс внутреннего регистра, 2 непосредственно адресуемый регистр в связи с этим становиться неудобно передавать параметры,
так как получается следующего вида манипуляции
1. устанавливаем в первом порту номер регистра для параметра 1
2. записываем параметр в порт 2
Ересь. Возьмите ОДИН 8-битный порт. Останется ещё 8 бит (старшая половина адреса) для адресации 256 регистров вашей железяки.
Для тугодумов: В СПЕКТРУМЕ ИМЕЮТ ЗНАЧЕНИЕ МЛАДШИЕ 8 РАЗРЯДОВ.
ld a,a // признак железяке что необходимо исполнить команду
Дурацкий метод. В том смысле, что может самопроизвольно что угодно
навыполняться. Через порты надёжнее.
[quote]
Основные требования к методу это
1. Скорость работы
[quote]
LD HL, paramters_address
LD BC, #xxyy ; xx -- ваш регистр, yy -- порт.
OTIR
Медленно?
captain cobalt
12.07.2006, 18:36
Сугубо по тактам память работает быстрее, чем порты.
Даже без DMA можно просто ловить обращения к определённым адресам памяти. Тогда можно совместить два способа:
LD DE,#xxxx - для передачи констант
LD (#zzzz),HL - для передачи переменных
Для программистов наиболее удобно программируемое устройство. Чтобы был свой процессор, ему даётся программа и дальше он самостоятельно работает по этой программе и не мешается.
Для тугодумов: В СПЕКТРУМЕ ИМЕЮТ ЗНАЧЕНИЕ МЛАДШИЕ 8 РАЗРЯДОВ.
Сам подумал что сказал?
LD HL, paramters_address
LD BC, #xxyy ; xx -- ваш регистр, yy -- порт.
OTIR
Медленно?
Да я уже вроде пришол к этому выводу
Сугубо по тактам память работает быстрее, чем порты.
Даже без DMA можно просто ловить обращения к определённым адресам памяти. Тогда можно совместить два способа:
Правильно я понимаю
Даем железка адрес буффера (BASE) в 8 байт (для командного пакета)
Потом пишем туда параметры, а скажем при записи команды в BASE+0 железяка воспринимает это как признак того что можеш начинать исполнение. То есть можно модифицировать один байт и записать (перезаписать) код команды и железяка начала ее исполнять
captain cobalt
12.07.2006, 19:32
Это, можно сказать, DMA.
А без DMA это
LD (#zzzz),HL
Железяка дешифрует #zzzz понимает что к ней обращаются, и ловит 2 байта. Такую команду можно использовать в цикле с разными значениями HL.
Ересь. Возьмите ОДИН 8-битный порт. Останется ещё 8 бит (старшая половина адреса) для адресации 256 регистров вашей железяки.
во-во и я о том же :)
LD HL, paramters_address
LD BC, #xxyy ; xx -- ваш регистр, yy -- порт.
OTIR
Медленно?
OTI
OTI
OTI
OTI
OTI
OTI
OTI
...
так суръезно быстрее :)
16т/байт, при том что даже память-память маскимально быстро копируется стеком за 10.5т/байт.
Ну не знаю что бы послать 16битный параметр надо 2 команды OUTI - получается 32 такта
В тоже время если порты замапить на карту памяти для передачи 16 битного параметра достаточно 16 таков ld (xxxx),HL к тому же становятся доступны такие пределсти как inc(HL) 11тактов; ld (hl),r8 7T; к тому же не надо делать порты доступные на чтение что выливается в упрощение железяки.
Плюс появляется такая прелесь как возможность посылать команды в обработчике прерываний, при том что основной поток тоже может слать команды.
Необходимо лиш сохранить область параметров в каком нить буфере.
OTI
OTI
OTI
OTIouti =)
а для модифицирующихся параметров разбавить outi обычными out
outi =)
гыгы ;)
тоже время если порты замапить на карту памяти
ну вот верной дорогой идем :) токмо мапить на память имеет смысл если тебе большие массивы слать нужно. когда речь идет о 16 байтах это не так важно. да и мапить на память через шину можно не куда попало. а всего лишь в одно место на один единственный сигнал без арбитража. т.е. это весьма ценный ресурс шины с которым нужно обращаться аккуратно (в отличии от портов). хотя если мапить параллельно с обычной памятью (т.е. только на запись в девайс) - можно и куда угодно :)
хотя если мапить параллельно с обычной памятью (т.е. только на запись в девайс) - можно и куда угодно
Именно!!! К тому же это не зависит от архетектуры шины. Этим финтом к тому же решается проблема с портами на чтение. И появляется некоторые команды подавать в обработчике прерывания (достаточно сохранить изменяемые параметры)
Цитата:
Сообщение от fk0
Для тугодумов: В СПЕКТРУМЕ ИМЕЮТ ЗНАЧЕНИЕ МЛАДШИЕ 8 РАЗРЯДОВ.
Сам подумал что сказал?
"Ларченко и Родионов" на соответствующей странице. Спорить будешь?
В тоже время если порты замапить на карту памяти для передачи 16 битного параметра достаточно 16 таков ld (xxxx),HL к тому же становятся
Через память быстрей на пару тактов (собственно те такты, что "вводятся дополнительно в цикле ввода-вывода).
Вопрос в том, куда замапить. В спектруме неположено вместо ПЗУ или ОЗУ чёрт знает
что "замапливать". Хотя вместо ПЗУ можно. В том смысле, что шина позволяет. Через ОЗУ
никак (имеются ввиду адреса 0x4000--0xffff). Но это тоже -- прямой путь к проблемам несовместимости и неудобство для кодера (нужно отслеживать чего там в ПЗУ).
Вопрос в том, куда замапить. В спектруме неположено вместо ПЗУ или ОЗУ чёрт знает
что "замапливать". Хотя вместо ПЗУ можно. В том смысле, что шина позволяет. Через ОЗУ
никак (имеются ввиду адреса 0x4000--0xffff). Но это тоже -- прямой путь к проблемам несовместимости и неудобство для кодера (нужно отслеживать чего там в ПЗУ).
Железяка следит за шиной адреса шиной данных и nMREQ nWR и когда процессор записывает в нужную нам область мы сохраняем внутри железки и нет никакой совместимости, далее если мапить на облать ПЗУ то теряется возможность читать что что записали, и еще облать где размещаются регистры можно будет указывать программисту
Wladimir Bulchukey (500:95/462)
14.07.2006, 16:34
Здравствуй(-те), Victor...!
12 Июл 06 19:45, Victor Ronin -> All:
так и работает v9990 между прочим - указываешь стартовый адрес, и пошел
пхать байты подряд :))))
Hу почему же сразу 9990... И 9958, и 9938 это умели. Это изначально было классикой обращения к видеопамяти MSX.
С наилучшими - Wlodek # wlblack()newmail.ru # http://wlodeks.narod.ru
[ZX] [500:95/462@ZXNet] [2:5016 Forever] [Golyanovo] [Старые русские]
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot