PDA

Просмотр полной версии : Передача параметров хитрой железке



ZEK
12.07.2006, 16:19
Граждане программеры, возник вопрос: щас прорабатывается концепция хитрой железки, и вот возникла необходимость железяке передавать команды и параметры, железяка достаточно умная теоретически умеет прослушивать шину спекка и соответствующим образом реагировать. В общем нужна помощь искушонных в 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. предусмотреть возможность что количество параметров может быть непостоянно

И еще так как тема относиться вроде бы к железяке добавлю что железяку тут не обсужаю, важно мнение программистов которые теоретически будут работать с данным делом и важна оптимальность взаимоотношения железяки и программаного обеспечения

skyther
12.07.2006, 16:29
Можно сделать так: 2 порта регистр команд/состояния и регистр данных. Шлем команду "записать данные в регистр N", протом шлем необходимое количество байт в рег данных. Чтение аналогично. 256 команд надеюсь хватит ;)

Ronin
12.07.2006, 16:38
классические порты незачем бояться :) или расшаренная память как самый быстрый вариант кидания массивов.


Шлем команду "записать данные в регистр N", протом шлем необходимое количество байт в рег данных.

так и работает v9990 между прочим - указываешь стартовый адрес, и пошел пхать байты подряд :)))) OUTI не слишком тормознее стекового копирования, вполне сносно. и достаточно просто чтобы юзать.

ZEK
12.07.2006, 17:06
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 происходит прерыание Умная железка могла бы прослушивать их и вести себя соответственно.

ZEK
12.07.2006, 17:39
Можно прослушивать только команду LD и брать её непосредственные операнды.
Код будет выглядеть так:
Думали над таким вариантом, трабл в том что если в цикле смыкать такую конструкцию, то прийдется делать самомодифицируищейса код, да и результат вроде медленней получается чем при использовании outi (хотя таблички под рукой нет мог и соврать).
Склоняюсь наверное к варианту работы с блочными командами ввода вывода у нее 2 плюса
1. не надо будет сильно извращаться
2. реализация железяки проще будет

Ronin
12.07.2006, 18:03
ут вот в чем вопрос допустим тебе штук 10 одинаковых команд послать надо они только отличаются скажем одним параметром, а параметр в цикле вычисляется получаются такие телодвижения

Для начала выделяем где нить буфер для комадного пакета

заполняем его
при помощи outi запихиваем в железяку
вычисляем параметр
правим буфер
и все сначала

а как этот самый параметр у тебя планируется править когда он уже залитый в FIFO буфере лежит :)
ну и кучка pop hl - тоже время как бы кушает-то :)

а можно не ипать мозги а повесить 256 байт обычного озу на старший байт (a8-15) порта и править эти команды хоть вдоль хоть поперек.

ZEK
12.07.2006, 18:14
Нечетко выразился

Просто ты можеш в регистре нужные манипуляции провести и послать заново push hl. В общем варант с outi все самый оптимальный выходит.

Ronin
12.07.2006, 18:29
а мне память на портах больше нравица ;)

fk0
12.07.2006, 18:33
Так как планируется свести к минимуму колво портов в адресном пространстве машинки мы добавляем всего 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 - для передачи переменных

Для программистов наиболее удобно программируемое устройство. Чтобы был свой процессор, ему даётся программа и дальше он самостоятельно работает по этой программе и не мешается.

ZEK
12.07.2006, 18:39
Для тугодумов: В СПЕКТРУМЕ ИМЕЮТ ЗНАЧЕНИЕ МЛАДШИЕ 8 РАЗРЯДОВ.
Сам подумал что сказал?


LD HL, paramters_address
LD BC, #xxyy ; xx -- ваш регистр, yy -- порт.
OTIR

Медленно?
Да я уже вроде пришол к этому выводу

ZEK
12.07.2006, 18:45
Сугубо по тактам память работает быстрее, чем порты.
Даже без DMA можно просто ловить обращения к определённым адресам памяти. Тогда можно совместить два способа:

Правильно я понимаю
Даем железка адрес буффера (BASE) в 8 байт (для командного пакета)
Потом пишем туда параметры, а скажем при записи команды в BASE+0 железяка воспринимает это как признак того что можеш начинать исполнение. То есть можно модифицировать один байт и записать (перезаписать) код команды и железяка начала ее исполнять

captain cobalt
12.07.2006, 19:32
Это, можно сказать, DMA.

А без DMA это
LD (#zzzz),HL

Железяка дешифрует #zzzz понимает что к ней обращаются, и ловит 2 байта. Такую команду можно использовать в цикле с разными значениями HL.

Ronin
13.07.2006, 09:24
Ересь. Возьмите ОДИН 8-битный порт. Останется ещё 8 бит (старшая половина адреса) для адресации 256 регистров вашей железяки.

во-во и я о том же :)


LD HL, paramters_address
LD BC, #xxyy ; xx -- ваш регистр, yy -- порт.
OTIR

Медленно?

OTI
OTI
OTI
OTI
OTI
OTI
OTI
...

так суръезно быстрее :)
16т/байт, при том что даже память-память маскимально быстро копируется стеком за 10.5т/байт.

ZEK
13.07.2006, 10:40
Ну не знаю что бы послать 16битный параметр надо 2 команды OUTI - получается 32 такта

В тоже время если порты замапить на карту памяти для передачи 16 битного параметра достаточно 16 таков ld (xxxx),HL к тому же становятся доступны такие пределсти как inc(HL) 11тактов; ld (hl),r8 7T; к тому же не надо делать порты доступные на чтение что выливается в упрощение железяки.

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

jtn
13.07.2006, 17:59
OTI
OTI
OTI
OTIouti =)
а для модифицирующихся параметров разбавить outi обычными out

Ronin
14.07.2006, 09:55
outi =)
гыгы ;)


тоже время если порты замапить на карту памяти

ну вот верной дорогой идем :) токмо мапить на память имеет смысл если тебе большие массивы слать нужно. когда речь идет о 16 байтах это не так важно. да и мапить на память через шину можно не куда попало. а всего лишь в одно место на один единственный сигнал без арбитража. т.е. это весьма ценный ресурс шины с которым нужно обращаться аккуратно (в отличии от портов). хотя если мапить параллельно с обычной памятью (т.е. только на запись в девайс) - можно и куда угодно :)

ZEK
14.07.2006, 10:20
хотя если мапить параллельно с обычной памятью (т.е. только на запись в девайс) - можно и куда угодно
Именно!!! К тому же это не зависит от архетектуры шины. Этим финтом к тому же решается проблема с портами на чтение. И появляется некоторые команды подавать в обработчике прерывания (достаточно сохранить изменяемые параметры)

fk0
14.07.2006, 15:03
Цитата:
Сообщение от fk0
Для тугодумов: В СПЕКТРУМЕ ИМЕЮТ ЗНАЧЕНИЕ МЛАДШИЕ 8 РАЗРЯДОВ.

Сам подумал что сказал?

"Ларченко и Родионов" на соответствующей странице. Спорить будешь?

fk0
14.07.2006, 15:07
В тоже время если порты замапить на карту памяти для передачи 16 битного параметра достаточно 16 таков ld (xxxx),HL к тому же становятся

Через память быстрей на пару тактов (собственно те такты, что "вводятся дополнительно в цикле ввода-вывода).

Вопрос в том, куда замапить. В спектруме неположено вместо ПЗУ или ОЗУ чёрт знает
что "замапливать". Хотя вместо ПЗУ можно. В том смысле, что шина позволяет. Через ОЗУ
никак (имеются ввиду адреса 0x4000--0xffff). Но это тоже -- прямой путь к проблемам несовместимости и неудобство для кодера (нужно отслеживать чего там в ПЗУ).

ZEK
14.07.2006, 15:51
Вопрос в том, куда замапить. В спектруме неположено вместо ПЗУ или ОЗУ чёрт знает
что "замапливать". Хотя вместо ПЗУ можно. В том смысле, что шина позволяет. Через ОЗУ
никак (имеются ввиду адреса 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] [Старые русские]