Приступим, помолясь.
Давате пройдём вдоль алгоритма...
ВНИМАНИЕ!
В действительности здесь ПО ОШИБКЕ описаны вычисления по оси Y, а алгоритм касается оси X. (Различие пинов для Джойстика и Мыши!)
Сам алгоритм верный. См. последнее примечание!
rdport
1. В Акумулятор, данные порта грузятся командой
LDA (LoaD Accumulator)
lda PORTA ; %EWSNewsn
2. Теперь надо избавится от данных CJ1. Делается это командой
LSR (Logical Shift Right) она сдвигает байт на один бит вправо, заполняя слева недостающий бит слева нулём ...
lsr a
lsr a
lsr a
lsr a ; %0000EWSN
3. Очищенный от CJ1 байт сохраняем на стек командой
PHA (PusH Accumulator)
Теперь байт и в Аккумуляторе и на стеке
pha
4. Теперь избавляемся от данных по оси X содержащихся в старшем дибайте ниббла командой
AND (AND with Accumulator)
Эта команда сохраняет всё, что под единицами маски и обнуляет остальное
and #%00000011 ; %000000SN
5. Пора формировать СМЕЩЕНИЕ по таблице движений movtab.
Данная таблица содержит значения (-1),0,(+1), при этом в Атарьской знаковой системе (-1)=255.
(Просто начиная со 128, автоматически устанавливается флаг процессора N - Negative), итак:
(-1) - движения нет, просто сохраняем Y в ypos
0 - движение вниз, значит координату экрана по y надо уменьшить
1 - движение вверх, значит координату экрана по y надо увеличить
Важная заметка!
переменная oldy имеет следующую структуру, полученную при инициализации/формировании: %0000sn00. Увидите далее...
ORA (OR with Accumulator) устанавливает соответствующие маске биты в 1
ora oldy ; %0000snSN, где sn - старое значение из oldy
То есть из двух Грейкодов, старого и нового, мы сформировали в Аккумуляторе однозначный ниббл, (значения от 0 до 15) являющийся смещением в таблице movtab.
6. Смещение будем задавать в регистре X командой
TAX (Transfer Accumulator to X)
tax ; %0000snSN в X
7. Смещение задано. Избавимся от старшего дибайта в Аккумуляторе.
and #%00000011 ; %000000SN
8. Формируем новое значение oldy (См. Заметку...) командой
ASL (Arythmetic Shift Left) - Сдвигает влево биты в аккумуляторе, заполняя недостающие справа нулями.
(Арифметический, потому, что учитывает переполнение, но нам это не нужно.)
asl a
asl a ; %0000sn00
9. Инициализируем переменную этим значением командой
STA (STore Accumulator to memory)
sta oldy
10. Всё готово для обработки данных экрана и клиппирования области экрана!
Заметка:
Клиппирование - это проверка на невыход курсора за область экрана.
; Загружаем координату по Y в Y-рег
ldy ypos
; Индекс в таблице задан в X-рег ранее, читаем данные в таблице
lda movtab,x
; Учитывая инфо из пункта 5. исследуем полученное и осуществляем соответствующую обработку
bmi story ; (-1) - просто сохраняем
bne decry ; (+1) - уменьшаем координату
incry
iny ; (0) - иначе, увеличиваем координату
cpy maxy ; Сравниваем с MAX значением...
bcc story ; ... если в зоне экрана, просто сохраняем
decry
dey ; ... при выходе за экран, уменьшаем координату (возвращаем в экран)
cpy miny ; Те же действия с MIN значением
bcc incry ; ... при выходе за экран, увеличиваем координату
story
sty ypos ; Просто сохраняем координату
...
Вот такой вот алгоритм для обработки оси Y
Чтобы обработать ось X, нужно сначала прочитать со стека сохранённое значение, затем избавиться от данных по оси Y и далее, действовать по этому же алгоритму
Примечание:
Дьявол прячется в мелочах.
Я честно запрограммировал с нуля хендлер, но он внезапно стал алгоритм по Y применять к X и наоборот.
Когда я догадался посмотреть на выложенные в предыдущих постах картинки портов я заметил, что в STM1 - другое расположение дибайтов по направлениям, чем в джойстике!!! Посмотрите сами!
Вот правильный код:
Код:
; This handler must be in interrupt (DLI or TIMER)
; It may read mouse near 800 times/sec
rdport
;
; handler for X
lda PORTA
lsr a
lsr a
lsr a
lsr a
pha
and #3
ora oldx
tax
and #3
asl a
asl a
sta oldx
ldy xpos
lda movtab,x
bmi storx
bne decrx
incrx
iny
cpy maxx
bcc storx
decrx
dey
cpy minx
bcc incrx
storx
sty xpos ; Datum for PMG
;
; The same for Y
pla
lsr a
lsr a
and #3
ora oldy
tax
and #3
asl a
asl a
sta oldy
ldy ypos
lda movtab,x
bmi story
bne decry
incry
iny
jmp checky
decry
dey
checky
cpy miny
bcc incry
cpy maxy
bcs decry
story
sty ypos ; Datum for PMG
...
; Program Variables
oldx .by 126
oldy .by 128
xpos .by 126
ypos .by 128
maxx .by 208
maxy .by 224
minx .by 48
miny .by 32
;
; The Indextable (-1)=no action!
movtab
.by 255,1,0,255,0,255,255,1,1,255,255,0,255,0,1,255