Ну по идеи чисто в теории такая ситуация может возникнуть, если между парой записей произойдет вызов nmi. Хотя это весьма странно, так как к этому моменту работу с PPU уже надо бы завершить.
Само по себе NMI не сбрасывает адрес тоже. Просто там может быть, код который тоже делает запись в vram, или даже просто строчка BIT PPU_STATUS.
Только чтение PPU_STATUS в основном цикле в этом случае не поможет, код всё равно 'посыпется'. Потому что тогда nmi может проскочить и 'между строк' установки адреса, или просто в цикле записи в PPU_DATA.
Поэтому, если у тебя много данных для записи (более 1 фрейма по времени) то NMI отключают вместе с дисплеем (или можно в самом nmi вначале добавить 'флаг'), а если у тебя записи в пределах vblank или даже экрана, то случайно/повторно в текущем кадре nmi сработать не может.
Добавлено позже:При этом в _GOTOXY можно передавать не только числа (константы), но и регистры или переменные. Скажем: _GOTOXY #10, Y - установить курсор в строку с номером Y (регистр) в позицию 10.
Понятно, ну минимально можно сделать функцию вместо макроса .macro _PRINT , чтобы не забивать ром однотипным кодом (передавать адрес строки). Если скорость не важна, можно даже сделать и отдельную функцию для установки адреса сделать вместо макроса, а в макросе оставить только вычисление A и Y.
proc_set_ppu_addr:
STA PPU_ADDRESS
STY PPU_ADDRESS
RTSЕсли наоборот нужна скорость , можно и в столбик строчки писать (такое тоже встречается):
; 'PRESS START'
LDX #'P'
STX PPU_DATA
INX ; R'
STX PPU_DATA
LDA #'E'
STA PPU_DATA
LDY #'S'
STY PPU_DATA
STY PPU_DATA
LDA #' '
STA PPU_DATA
STY PPU_DATA ; 'S'
INY ; 'T'
STY PPU_DATA ; 'T'
LDA #'A'
STA PPU_DATA ; 'A'
STX PPU_DATA ; 'R'
STY PPU_DATA ; 'T'Касаемо вычислений, можно так попробовать:
offset:
LDA #>SCR_BASE ; SCR_BASE = $2000
ORA sreg + 1
STA PPU_ADDRESS
TXA
ORA sreg
STA PPU_ADDRESS
RTS