Пока держишь на порту сигнал.
Вид для печати
Обнаружил ошибку в своём коде ana 0c0h - неправильно, нужно ani 0c0h
Проверить на реале смогут только завтра.
Pretty 8080 Assemler
Он ошибки подсвечивает, но если не просматривать весь текст, то можешь не узнать о них и скомпилировать как есть.
А текст я набираю в NotePad и уже оттуда переношу в Pretty 8080 Assemler
Если же набирать текст в Pretty 8080 Assemler, то ошибки сразу видно.
Надеюсь, что ты пользуешься современной версией с интегрированным редактором, а не допотопной.
Я пользуюсь вот этой версией https://svofski.github.io/pretty-808...er/tvnoise.asm
Pretty 8080 Assemler - мне нравится. А ошибки это моё - не просмотрел текст и в итоге прошляпил.
Когда набираешь в нем, текст сразу подсвечивается красным и потребности в какой-то дополнительной диагностике нет. С копипастой это не так заметно. Лучше бы мне сделать защиту от таких ситуаций и не запускать программу с ошибками. Это на будущее.
Баг или фича?
Вложение 75932
Нажал кнопку RUN
получил первый TEST
в английской раскладке попробовал набрать TEST получил на экране TECT но прога запустилась
потом попробовал набрать TECT получил ТЕЦТ и прога не запустилась
artyr_n, ТЕЦТ == tect, а надо писать ТЕСТ, или test ;) Почему раскладка случилась русская я не знаю, но РУС/LAT в этом эмуляторе на кнопке F6.
Исправленная версия кода - успешно прошла проверку на реальном Векторе и реальном Джойстике П :)
Спасибо всем кто помог мне в этом вопросе !!
Вот окончательный вариант моего кода опроса "джойстика П" (может кому пригодится)
; этот код находится в подпрограмме прерываний
; вначале опрашивается клавиатура и результат опроса заносится в ячейку KEYKOD
; если на клавиатуре ничего не было нажато то в ячейку KEYKOD заносится код того что ничего не нажато
; далее идёт опрос "джойстика П" - результат опроса заносится тоже в ячейку KEYKOD
; таким образом работает и клавиатура и джойстик
; ============= Joystik P
; =============
JOY:
in 06h ; читаем порт где подключён джойстик П
cma ; инвертируем для удобства обработки
mov l,a ; сохраняем значение сигнала
ani 128 ; выделяем бит первой кнопки
cpi 128 ;
jnz joykon2asd
mvi a,0FEH ; эта кнопка джойстика аналогична нажатию кнопки "TAB" клавиатуры в игре
sta KEYKOD ; записываем в ячейку для дальнейшей обработки в основном коде
jmp joykon5 ; переход на конец опроса джойстика если было нажатие кнопки
joykon2asd:
mov a,l ; выделяем бит второй кнопки
ani 64 ;
cpi 64 ;
jnz joykon3asd
mvi a,0FEH
sta KEYKOD
jmp joykon5
joykon3asd:
mov a,l
ani 1 ; выделяем бит направления вправо
cpi 1 ; vpravo ?
jnz joykon2
mvi a,0BFH
sta KEYKOD
jmp joykon5
joykon2:
mov a,l
ani 2 ; выделяем бит направления влево
cpi 2 ; vlevo ?
jnz joykon3
mvi a,0EFH
sta KEYKOD
jmp joykon5
joykon3:
mov a,l
ani 4 ; выделяем бит направления вверх
cpi 4 ; vverx ?
jnz joykon4
mvi a,0DFH
sta KEYKOD
jmp joykon5
joykon4:
mov a,l
ani 8 ; выделяем бит направления вниз
cpi 8 ; vniz ?
jnz joykon5
mvi a,7FH
sta KEYKOD
joykon5:
metamorpho, небольшое замечание: в этом коде можно легко убрать все команды "cpi XX", т.к. стояшие перед ними "ani XX" уже устанавливают признак Z при отсутствии единицы в проверяемом разряде. Это сократит код на 12 байт и ускорит его, если не ошибаюсь, на 48 тактов.
- - - Добавлено - - -
И ещё запись "sta KEYKOD" можно было бы сделать всего один раз... В общем, принцип "любую программу можно сократить как минимум на одну команду" работает. :)
Влезу не в свою стихию (кодил для Z80), но захотелось поучаствовать из спортивного интереса.
Почитал доки по 580ВМ80 - это же аналог i8080, то есть лайтовая версия Z80. Так что вперед =)
Можно сократить процедуру, проверяя кнопки сдвигом аккумулятора вместо AND с перезагрузкой каждый раз.
Переделал обработку условий: вместо кучи jmp и jr (jnz) теперь однобайтовые ret, экономим память.
То есть подразумевается, что JOY вызывается по call, а не просто вставлена в текст кода.
Кстати, в процедуре или опечатка, или так и должно быть, но обе кнопки (1 и 2) дают значение FE на выходе.
Писал с учетом этого, но если должны выходить разные значения - раскомментировать команду "mvi l,число".
Убрал кучу лишних меток и переставил местами проверки направлений из-за положения битов в регистре.
Как понял, если ничего не нажимали - значение в KEYKOD не переписывается.
Получится примерно так (если где ошибся в написании команды - прощу пардонить):
JOY:
in 06h ; читаем порт джойстика
cma ; инвертируем
call joy_test ; проверки выделены в подпрограмму для замены jmp и jr на ret'ы
ret nc ; выходим без записи кода, если ничего не жали
mov a,l ; получаем код
sta KEYKOD ; записываем код
ret ; конец процедуры
joy_test:
mvi l,0FEH ; код "ТАБ"
rlc ; проверяем бит первой кнопки, флаг С=1 - кнопка нажата
ret c; кнопка нажата - возврат в JOY
; mvi l,число ; - это если нажатия кнопок 1 и 2 различаются, иначе не нужна
rlc ; проверяем бит второй кнопки, они равнозначны с 1-й, судя по исходному коду
ret c; любая из кнопок 1 и 2 дает код клавиши "ТАБ"
rlc
rlc ; пропускаем 5-й и 4-й незначащие биты
mvi l,07FH ; код "вниз"
rlc ; проверяем бит направления (3-й, значение 8)
ret c
mvi l,0DFH ; код "вверх"
rlc ; вверх (2-й, значение 4)
ret c
mvi l,0EFH ; код "влево"
rlc ; влево (1-й, значение 2)
ret c
mvi l,0BFH ; "код вправо"
rlc ; вправо (0-й, значение 1)
ret ; безусловный выход, все проверено
Итого процедура сократилась раза в два. Прошу написать точные числа исходной и моей, лень считать =)
Да, еще кое-что: в данном виде процедуры не предусматривают обработку диагональных направлений,
то есть нажатия сразу вверх+влево, например. При этом на джойстике может быть еще и огонь нажат.
Хотя на любой платформе с любым джойстиком возможно движение по диагонали + огонь сразу.
reddie, спасибо !!
Отличный вариант оптимизации кода, буду применять эти идеи в будущем.
Пользуйтесь на здоровье)) но в будущем при разработке блока управления, если предполагается джойстик, лучше сразу заложить возможность диагональных нажатий,
а также одновременных нажатий кнопки "огонь" или что там на ней будет, да и второй кнопки тоже. Код усложнится, зато игровой процесс станет интереснее.
Реализация клавиатуры Вектора, как понимаю, отслеживает только одну клавишу в момент времени (как на БК), это плохо, но терпимо. Для игр есть джойстик.
А чтобы реализовать момент с "диагоналями и fire", процедура скана выдает на выходе не код "клавиши", а суммарную маску нажатых клавиш.
То бишь, в принципе, можно брать прочитанный байт из порта джойстика и обрабатывать все "нажатые" биты, изменяя с их учетом координаты спрайта, например.
Если были нажаты биты влево и вверх - уменьшаем Х, увеличиваем Y (или уменьшаем, смотря откуда считается начало экрана, сверху или снизу).
Для особого прикола можно одновременно обработать и влево, и вправо, главное, чтобы при этом итоговая координата не изменилась (+1-1 равно ноль).
Зачем? Для сопряжения с управлением клавиатурой. Сканируем коды с нее (если клава позволяет, как на Спектруме, опросить сразу несколько клавиш)
или код (если можно опросить только одну), интерпретируем в коды направлений/нажатий и суммируем это с байтом из порта джойстика по OR.
На выходе получим универсальное значение от всех устройств, с которым проще работать. Надеюсь, идея понятна. С реализацией, если что, поможем.
Несколько отвлеченное рассуждение. Авторы УСПИД/ПУ джойстика похоже собирались максимально упростить одновременный опрос джойстика и клавиатуры (если огонь - ЗБ). Единственный странный момент - они зачем-то поменяли вверх и вниз по сравнению с клавиатурой. Вот раскладка -П/-С более загадочная.
Не помню, когда последний раз пользовался возвратом из подпрограммы по условию...
В i8080 это вроде-бы мнемоника не "RET C", а "RC" (но зависит от компилятора, возможно и ret c переварит).
Но если бы я делал обработку джойстика, то я бы вообще не занимался её обработкой, а наложил бы считанный код на код считанный из клавы, преобразовав его предварительно с помощью таблицы. Там таблицы всего 16 байт, из них полезных 9 байт.
В таблице коды соответствия состояния джойстика и клавиш клавиатуры.
Для простоты, таблицу расположил-бы начиная с адреса 0103h, тогда получился-бы примерно такой код.
Главное преимущество, с моей точки зрения, что эта часть программы всегда выполняется одинаковое количество тактов вне зависимости от того используется-ли джойстик, и какие контакты на нём замкнуты... предсказуемость времени выполнения кода...Код:in 06
ani 00Fh
adi 003h
sta adrk+1
adrk:
lda 0103h
mov b,a
lda KEYS (адрес где хранится уже считанный код клавы ряда с клавишами курсора)
ana b (наложил джойстик на клавиши)
sta KEYS (и пусть теперь основной код обработки нажатий клавиш разбирается)
;
in 06
ani 0C0h (выделение кнопок джойстика)
... тут код совмещения с нужными клавишами клавы, их меньше - таблица уже не нужна.
Если "нормализовать" код считанный из УСПИД-а, то и его таким методом можно юзать... таблица там будет возможно другая, но дело поправимое...
Ну, на Спектруме (Z80) условные call и ret довольно распространенная практика. Таблицы там тоже юзают, тут просто суть задачи была максимально сократить код.
Любые таблицы это дополнительные байты, плюс 16 байт - это лишь кнопки направлений, без кнопок "огонь1" и "огонь2" (или как их принято называть на Векторе).
Про совмещенную обработку клавы+джойстика - да, в идеале так и делается. metamorpho, полагаю, учтет это в будущем =)
Его код опроса напоминает обработку бейсик-программы компилятором, но ему простительно, он только учится. Главное - подсказывать, как и что.
А если в начале сделать инверсию кода, то можно обойтись таблицей в 11 байт, из которых 9 полезных, т.к. одновременное срабатывание контактов вверх и вниз не возможно, а это будут старшие 4 кода, плюс ещё одна комбинация одновременного нажатия вправо/влево.
- - - Добавлено - - -Код:in 06
cma
ani 0F
...
[QUOTE=reddie;1126966]Ну, на Спектруме (Z80) условные call и ret довольно распространенная практика. ...QUOTE]
Из-за близости архитектуры процессоров, можно предположить, что использование call и ret с условиями, это вопрос стиля программирования, а не особенность программирования на конкретном железе.
- - - Добавлено - - -
Можно даже без инверсии использовать таблицу в 11 байт, нужно только предусмотреть смещение адреса начала таблицы на 5 байт вниз, т.к. они не будут востребованы.
Cогласен, это больше вопрос стиля, да и любую программу можно написать тысячью способов.
Но, учитывая, что Z80 - это 8080 (ВМ80) "на спидах", на нем полет фантазии шире.
Например, сдвиги любых регистров, индексные регистры и много чего еще. Но это к джойстикам не относится, оффтоп.
Имеем четыре типа джойстиков. Как они распределялись по популярности/распространённости? То есть, какие прежде всего стоит поддерживать у себя в игре?
(Пока предварительно считаю, что это Джойтик-П и Джойстик-С.)
Джойстики "П" и "С" - это фактически аппаратные паты джойстиков, либо для игр на два игрока, либо предусматривать выбор не только типа Джойстика, но и конкретного джойстика ид пары - для корректности... если в игре обрабатывается/используется только один джойстик.
Причём нужно помнить, что Джойстик-С - это фишка .02-го Вектора.
Если в игру вставляется выбор джойстиков, воткнуть ещё и УСПИД - по идее не должно представлять особой проблемы.
А нельзя опрашивать сразу П, С и УСПИД? Или, если почему-то возникает конфликт, ждать что первым будет потрогано и на основе этого делать выбор контроллера.
А что например может там так шуметь, постоянно дергая биты без провокации?
Можно детектировать .02 или 6128, что автоматом даст -С. Инициализируем и опрашиваем -П, если там 1 во всех битах кнопок и направлений, то считая, что пользователь в данный момент не трогает джойстик, дальше можем опрашивать -П (если джойстика там нет - ничего страшного, главное чтобы значения порта не менялись и в битах джойстика оставались 1). -С и -П легко опрашивать параллельно, только надо отключить соответствующие inы (заменить на mvi a,), если -С или -П не обнаружены.
На экране написано "PRESS FIRE TO START".
По идее, можно автоматом выбирать джойстик по нажатию Fire на нём - изменившийся битик покажет, какой джой дальше опрашивать.
- - - Updated - - -
Таки сделали аутентичный Arcade Volleyball или нет?
В 2010 я делал клон под Dingoo, на чистом Си: https://boards.dingoonity.org/dingoo...olleyball-0-2/
Откопал сегодня свой старый джойстик 90-ых годов...
Не помню уже его историю... от какого компа он был в оригинале...
На основании две кнопки. На самом джойстике обе кнопки конструктивно представляют из себя одну кнопку, т.е. под кнопками расположены контактные/пружинные пластины, которые замыкаются между собой. :(
На шнурке уже мною сделан переходник на стандарт "Джойстика-П", с гнездом для подключения к переходнику второго джойстика.
И оставлен "родной" штекер DIN-5pin. Корпус штекера звонится как общий, контакты - это направления и спаренная кнопка джойстика. Судя по всему, в оригинале, кнопки на основании вообще не использовались.
Если пластик не треснет от старости, нужно подумать, как разделить кнопки на джойстике... разберу, может микрики получится воткнуть...
А это мой джойстик от Вектора:
Вложение 75985
Историю его помню: покупал в магазине электроники "Алиса" (был такой в Волгограде), не думаю, что он был для какого-то конкретного компа, продавался без разъёма. Сам его переделывал -- контакты направлений заменил микриками, кнопки там две и они выведены отдельными проводами. Подключался в разъём ПУ в двух вариантах (переходник не помню где), и непосредственно к кнопкам клавиатуры, играл им в играх даже без поддержки джойстиков.
У вектора были вроде "родные" джойстики. По-крайней мере в комплекте с ПК6128 шли джои. Фотографировать пока некогда :-(
Подскажите, как правильно инициализировать порты, чтобы все джойстики работали? - в смысле, чтобы успешно опрашивались.
Вот с такой инициализацией:
mvi a,60h \ out 5
mvi a,83h \ out 4
- под эмулятором VV 7.02 - работает джой-С (сразу оба порта 0e/0f) и джой-П (порт 06), но НЕ работает УСПИД (порт 07 - все нули);
- под MiSTer FPGA - работает джой-С (порт 0e) и УСПИД (порт 07), но НЕ работает джой-П (порт 06 - все единички).
Приложил свой тест в этом сообщении - он сделан на основе теста от @svofski - может кто-то проверит на реале?
Для одновременного опроса -П и УСПИД я бы попробовал инициализировать так
mvi a,92h (или 93h, вряд ли будет разница)
out 4
При этом оба -П теоретически должны быть запараллелены (опрашиваются одновременно).
А -С инициализировать не надо, да и не получится, но желательно детектировать его наличие. Возможны разные варианты, но я бы предложил остановиться на консервативном - если из 0E/0F читается FF, то -С есть (и даже если его на самом деле нет, это ничего не испортит и ничему не помешает).
Да, с инициализацией
mvi a,60h \ out 5
mvi a,92h \ out 4
в VV 7.02 заработали все три джоя - уже прогресс. Спасибо!
По-прежнему стоит вопрос - а что на реале? приаттачил тут поправленный бинарник.
Исходник тут - https://gist.github.com/nzeemin/db93...f8057cfb29be1a
Понятно ведь "зачем" - попытка отключить джойстики.
Просто последовательность должна быть наоборот:
сначала инит портов out 04, а уже потом вывод в них команд управления джойстиками out 05.
Только вариант:
mvi a,7fh \ out 5
возможно будет более корректным для "ПУ", т.к. значения "0" - обычно включают какую-нибудь периферию, исключение - старший бит включение внешнего ПЗУ при "1".