Какой элегантный способ чтения ввода контроллера для сборки NES (6502) на ca65?

В свободное время я начинаю изучать ассемблер 6502 для потенциального игрового проекта NES, и у меня возникли проблемы с настройкой чтения ввода контроллера. Мой опыт написан на C, поэтому я знаком с памятью и тем, как она работает, но управление потоком в ассемблере все еще ускользает от меня.

Поскольку я новичок, я решил, что мне следует начать с простого и использовать пошаговый метод, описанный в https://www.vbforums.com/showthread.php?858965-NES-6502-Programming-Tutorial-Part-5 . -Контроллер-Команды . Это хорошо работает, но это действительно повторяется и многословно.

Есть ли более элегантный способ сделать это, который не полностью превышает мои возможности? Я недостаточно знаю, чтобы интегрировать код из других источников без посторонней помощи.

https://wiki.nesdev.com/w/index.php/Controller_reading_code выглядит многообещающе, но я недостаточно понимаю его, чтобы использовать.

Спасибо за ваше время.

1 ответ

Контроллеры NES — это последовательные устройства, каждое из которых содержит внутренний сдвиговый регистр. Чтобы прочитать контроллеры:

  • установите от 1 до b0 4016 долларов; это заставит контроллеры начать непрерывную выборку своих входов и перезагрузку своего 8-битного сдвигового регистра;
  • установите от 0 до b0 4016 долларов; это приведет к тому, что контроллеры прекратят выборку своих входных данных и перестанут перезагружать свои регистры сдвига;
  • для контроллера 1 каждое чтение из $4016 возвращает младший значащий бит из регистра сдвига в b0 и вызывает сдвиг регистра;
  • для контроллера 2 $4017 выполняет эквивалентное чтение и сдвиг.

Входные данные возвращаются в порядке A, B, Select, Start, Up, Down, Left, Right.

Таким образом, первую часть этого контракта нельзя сильно улучшить. Вы неизбежно увидите что-то вроде:

      ; Get current controller inputs into their shift registers.
LDA #1
STA $4016
LDA #0
STA $4016

Предполагая, что вас интересуют все восемь входов и, например, только контроллер 1, тогда определенно будет как минимум восемь операций чтения из 4016 долларов. Поскольку это также строб для сброса того, что находится в сдвиговом регистре, лучше, чтобы они были только для чтения — без записи или чтения-изменения-записи.

Также, к сожалению, неверно, что биты с 1 по 7 равны 0. Так что, например, вы не можете просто ORAот 4016 долларов США и получать результаты постепенно. И ни один из неофициальных кодов операций не кажется таким уж полезным для удобной загрузки-и-И в этой ситуации.

Так что, если вы хотите собрать результаты в A, тогда все будет не так элегантно.

Из предоставленных вами ссылок:

Предложение vbforums.com состоит в том, чтобы загрузить от 4016 долларов восемь раз, каждый раз проверять младший бит и реагировать соответствующим образом в этом цикле. Оно использует AND #1(установить Z) и BEQ(для проверки) для проверки бита после загрузки, тогда как LSR(чтобы переместить бит 0 в перенос) и BCC(для пробы переноски) наверное, мне бы он был более элегантным в том смысле, что он немного компактнее.

Ссылка NesDev Wiki вместо этого переводит каждый отдельный бит ввода джойстика через перенос в другой байт, так что в итоге вы получаете 8-битное значение в памяти, равное тому, что когда-то было в сдвиговом регистре контроллера, и вы можете тестировать и манипулировать что на досуге.

Если ваша проблема просто «повторяющаяся и многословная», то я думаю, что проблема может быть в ваших инструментах, а не в оборудовании — ищите ассемблер макросов. Многие из них на один или два шага выше препроцессора C, поэтому в конечном итоге вам может понадобиться кодировать ту же последовательность шагов, что-то вроде:

      MACRO nextBit source destination {
    lda source        ; Read next bit from controller.
    lsr               ; Move bit to carry.
    ror destination   ; Roll bit from carry to top of local state.
} ENDMACRO

; Get controllers to reload their shift registers.
lda #1
sta $4016
lda #0
sta $4016

; Copy shift registers to local memory.
FOR n, 0, 8
    nextBit $4016 controller1State
    nextBit $4017 controller2State
NEXT

Это синтаксис макроса, используемый конкретным реальным ассемблером для BBC Micro, и почти наверняка не тот синтаксис макроса, который использует ваш ассемблер, потому что стандартизация очень мала. Но будет хороший компилятор макросов для NES, а работа компилятора макросов состоит в том, чтобы позволить вам расшифровывать повторяющиеся части без копирования и вставки.

Другие вопросы по тегам