Цитата Сообщение от atariki Посмотреть сообщение
ну вот допустим захотел я джойстиком погонять точку по экрану в gr.0, как мне логически рассуждать в ассемблере для написания этой программы ?
Добрый денёк, atariki.

Ну, чтобы пиксель гонять по экрану, надо объединить графику 0 с графикой 8.
Это сделать можно, но там свои проблемы...
А вот, чтобы погонять знакоместо (курсор) по экрану в ДОСе, могу предоставить ассемблерную программку...

Рассуждаем следующим образом...

1) Что гоняет курсор по экрану?
- При нажатии на клаве стрелки, код клавиши идёт в системную программу преобразования кодов в буквы(ATASCII) и окончательно оседает в однобайтовом теневом буфере ввода CH.
Таким образом, зная коды стрелок и анализируя положение джойстика, мы можем руководствуясь джойстиком, по нашему желанию подменять коды в регистре CH. Тогда при следующем VBI, наши коды будут двигать системный курсор.

2) Когда подменять коды в CH?
- Так как машинка не должна знать, что мы подменяем коды, надо делать это в прерывании по Вертикальному Бланку (по кадрам экрана).

3) Где поместить программу VBI?
- Программка достаточно короткая (~40 байт), чтобы быть помещена где угодно!!! В частности, я помещал её в конце аппаратного стека и стек никогда её не затирал.

4) Какой режим VBI выбрать?
- Я выбрал Immediate, так как у этого режима около 60 свободных циклов, но можно и Deferred - без разницы.

5) Какой будет скорость курсора?
- Нормальная для меня скорость курсора это считывание данных джойстика каждый пятый кадр экрана. (Счётчик кадров должен меняться от 4 до 0). Большие значения счётчика замедляют движение.

А вот и сама программа.
Код:
; Джойстик-курсор
; jc.com
        .ou jc.com

; ====================
; Ярлыки
SETVBV  =   $e45c    ; Вектор установки VBI.
SYSVBV  =   $e45f    ; Возврат на системный VBI.
STICK0  =   $0278    ; Теневой регистр джойстика.
RUNAD   =   $02e0    ; Адрес запуска программы
CH      =   $02fc    ; Теневой буфер текстовых кодов

; --------------------
; Константы
vbmode  =   6        ; Режим VBI=Immediate
speed   =   $04      ; Скорость курсора.
cur.up  =   142      ; Величины кодов стрелок...
cur.dn  =   143
cur.lt  =   134
cur.rt  =   135

; ====================
; Главная программа
        .or $0110    ; Конец стека
start   jmp init     ; Переход на подпрограмму инициализации
                     ; прерывания по VBI

; --------------------
; Блок данных
keytab  .by cur.up,cur.dn
        .by cur.lt,cur.rt
counter .by 2

; --------------------
; Инициализация прерывания VBI
init
        ldy #<vbi    ; LSB исполняемой части VBI 
        ldx #>vbi    ; MSB исполняемой части VBI
        lda #vbmode  ; Режим VBI
        jsr SETVBV
;
        rts          ; Возврат в ДОС после инициализации VBI

; ====================
; Подпрограмма исполняемой части VBI
vbi
        dec counter  ; Уменьшаем счётчик пропуска считываний джойстика.
        bne done     ; Если не дошел до нуля,
                     ; переходим на системный VBI.
        lda #speed   ; Если ноль,..
        sta counter  ; обновляем счётчик пропуска считываний джойстика.
;
        lda STICK0   ; Затем, считываем джойстик
        eor #$0f     ; Проводим проверку на движение ручки.
; Число $0f равно 15, а это значение, если ручка НЕ ДВИГАЛАСЬ!
; eor (Исключающее ИЛИ) ИНВЕРТИРУЕТ данные в Аккумуляторе и
; в случае, если там было 15, станет 0.

; При анализе положения ручки будут исследоваться уже ИНВЕРТИРОВАННЫЕ данные!!!

        beq done     ; Если ноль, джойстик не двигался и мы
                     ; переходим на системный VBI.
;
        ldx #$ff     ; Если двигался, устанавливаем в 255 (reset)
                     ; селектор считывания таблицы кодов стрелок.
                     ; По сути - это смещение в регистре X.
chkstk
        inx          ; Чтобы перейти к следующему значению в таблице,
                     ; увеличиваем смещение.
                     ; В случае, если мы реинициализировали селектор,
                     ; вспоминаем, что в однобайтных вычислениях $ff+$01=$00,
                     ; то есть смещение равно нулю и селектор показывает
                     ; на первое значение в таблице.
        lsr a        ; Так как в аккумуляторе у нас ИНВЕРТИРОВАННОЕ значение
                     ; данных джойстика, сдвинем логически биты вправо.
                     ; При этом сдвинутый бит помещается во флаг статуса Carry.
        bcc chkstk   ; Если в Carry ноль, значит в этом направлении
                     ; джойстик не двигался, проверяем следующее направление...
        lda keytab,x ; Если движение было, берём соответствующее значение
                     ; данных курсора из таблицы
        sta CH       ; и заносим их в теневой буфер CH
done
        jmp SYSVBV   ; переходим к системному VBI.