Код:
Кажется кто-то упоминал, что нужна программа для обработки джойстика...
Предлагаю программу Джеймса Коренталя для расшифровки положений джойстика.
Я думаю, она малопонятная, но самая быстрая.
Что мы думаем о джойстике?
Прежде всего он замыкает контакты. Может и попарно!
Все контакты джойстика нормально разомкнутые и при считывании аппаратного регистра джойстика
в разрядах дают логическую ЕДИНИЦУ!
При замыкании контакта, это приводит ЕДИНИЦУ к НУЛЮ! (Искра ушла в землю.)
Максимум числа джойстиков для Атари - 4. В новых моделях - 2.
Вот "Роза Ветров" положений джойстика:
N
NW NE
W C E
SW SE
S
Всего их 9, А значит 4Joy x 9Dir = 36 предложенных данных для разбора.
Вот почему в Бейсике такой разбор по значениям неприемлем!
Джойстик сильно абстрагирован от программ.
В частности, это означает то, что джойстик ориентируется НЕ НА ДАННЫЕ ПРОГРАММЫ, а только на свои!
То есть, когда мы тянем его вниз, то в лётном симуляторе самолётик-то летит вверх, и именно это означает,
что обработка данных джойстика лежит не на джойстике, а на программе!
Предлагаю битовую таблицу значений для различных положений джойстика:
.DIRECTION BINARY
HOR VER
. E W S N
.Center 1 1 1 1
.N 1 1 1 0
.NE 0 1 1 0
.E 0 1 1 1
.SE 0 1 0 1
.S 1 1 0 1
.SW 1 0 0 1
.W 1 0 1 1
.NW 1 0 1 0
То есть:
1. Коренталь обратил внимание, что Атарьские ГЕНИИ разделили младший Нибл на два полуНибла!
Младший полуНибл отвечает за Y (VER), Старший полуНибл отвечает за X (HOR).
Он знал, что любые данные, левее младшего полуНибла можно элиминировать с помощью инструкции AND #3.
DEC BIN
3 11
Эта инструкция обращает в ноль ВСЁ, что левее младшего полуНибла в байте, оставляя полуНибл неприкосновенным!
2. Кроме этого Коренталь знал, что чтобы скинуть младший полуНибл, если нам нужно исследование
ТОЛЬКО старшего полуНиббла (HOR), мы можем два раза сдвинуть значение Аккумулятора вправо, командой LSR A.
Это всё стало доступным благодаря Атарьцам!
Атарьские Гении разделили! выходные значения покоординатно и поконтактно следующим образом:
1. На всё определение данных отводится младший нибл байта.
2. младший полунибл отвечает за вертикаль!
3. старший полунибл отвечает за горизонталь!
Остальная часть байта не имеет значения.
Проблема дешифрации не столь очевидна.
Наша задача привести данные джойстика к значениям Диффирента по X или по Y!
Тогда, прибавляя дифферент по любой координате к текущему положению, мы получим новую координату!
Программа Бейсика, иллюстрирующая применение Ассемблерной программы вызывается следующим образом:
X=0,Y=1
FOR N=0 TO 3 : REM Это для 800-х для новых 0...1
DIR=X : REM For X
DX=USR(RDJ,N,DIR)
DIR=Y REM For Y
DY=USR(RDJ,N,DIR)
... Some ACTIONS like ? SMTH ... etc.
NEXT N : REM Возврат на начало цикла для считывания следующего джойстика...
Вид СТЭКА в Бейсике определяется Аргументами вызова USR!
Справа налево аргументы кладутся ПОСЛОВНО на стэк, Потом кладётся Число аргументов БАЙТ.
Многие из этих данных нам не нужны, так как Бейсик использует ТОЛЬКО двухбайтовые данные!
Соответственно, для представления однобайтовых данных нам не нужны старшие байты.
Кроме этого нам не нужно число аргументов вызова, до тех пор, пока это не существенно для нашей программы!
(Это когда вызов с переменным числом аргументов.)
Видим сразу, - в отличии от Ассемблера Бейсик Явно избыточен!
Вот наш Стэк:
Number of Arguments - 1 байт - TOP OF STACK
-------------------
MSB of JOYNUM
LSB of JOYNUM
-------------------
MSB of DIR
LSB of DIR
-------------------
...
LAST LSB of ... - BOTTOM of STACK
-------------------
Смотрим то, что нам не нужно...
1. Число аргументов нафиг!
2. Номеров джойстика мало, значит MSB нафиг!
3. Номеров направлений ваще два - MSB нафиг!
Итак, ПОМНИМ у нас есть пул джойстиков - STICK0...STICK3 (в Лучшем случае...)
Вспоминаем, что обращение к Аккумулятору ведёт себя как Экскаватор.
Всегда выбрасывает породу,.. и иногда загружает её в самосвал.
;Assembler Joystick Routine
;
; EQUATES
STICK0 = $0278
;
; VARIABLES
ANSWLO = $D4 ; Произвольный регистр
ANSWHI = $D5 ; ... на Нулевой странице.
;
.OPT LIST,OBJ
;
*= $0600
; CODES
PLA ; Нафиг число аргументов!
PLA ; Нафиг старший байт числа джойстиков!
PLA ; Берём младший байт числа джойстиков
TAX ; Это и будет побайтным смещением в пуле джойстиков!
PLA ; Нафиг старший байт направлений (всего два!)
LDA STICK0,X ; Читаем пронумерованный в цикле Бейсика джойстик
; На этом этапе, вершина СТЭКа содержит младший (существенный)
байт направления (0...1)
; который, командой PLP заносится в Регистр P-Процессорный статус
NV BDIZC - регистр P
PLP ; Берём флаг
P - ЭТО ИНДИКАТОР! Его значения могут быть учтены и считаны, но ... ПОЗЖЕ,
если это нужно ПРОГРАММЕ!
На процессор регистр НЕ ВЛИЯЕТ!
; Так как в регистре P - наше значение (0...1) Всегда МЛАДШИЙ бит! это = флаг Carry, то определяем направление...
BCS NOTX ; Если установлен то мы запрашиваем Игрек, пропуская X.
RDX LSR A ; Если X, сдвигаем
LSR A ; на 2 бита вправо...
NOTX AND #3 ; здесь, скрываем все данные старших битов, кроме интересующих нас.
SEC ; Готовим вычитание
SBC #2 ; Математическая обработка ...
BPL SAVEIT ; Если положительно
LDA #2 ; Если отрицательно
SAVEIT STA ANSWLO
LDA #0
STA ANSWHI
RTS
.END
Здесь мы приехали к расшифровке данных джойстика.
.DIRECTION BINARY PROGRAM ANSWER
HOR VER
. E W S N X-Val Y-Val
.Center 1 1 1 1 1 1
.N 1 1 1 0 1 0
.NE 0 1 1 0 2 0
.E 0 1 1 1 2 1
.SE 0 1 0 1 2 2
.S 1 1 0 1 1 2
.SW 1 0 0 1 0 2
.W 1 0 1 1 0 1
.NW 1 0 1 0 0 0
Караул!
ДОКТОР МЫ ЕГО ТЕРЯЕМ!
Ничего мы не потеряли!!!
Смотрим на X-Val.
Чтобы получить стандартные значения (-1 0 1), для смещений по координате X,
достаточно в Бейсике сделать DX=USR(...)-1
а для данных Y-val
достаточно в Бейсике сделать DY=1-USR(...)
Вот!