Для 6502 не помешает ссылка на перевод система команд 6502.
А с чего начать? с изучения платформы конечно же. Быстро для Atari и Apple II вряд ли получится.
принцип работы стека знаешь? надеюсь, что знаешь)
но на всякий случай — первый пришел, последний ушел.
допустим мы стек бросаем значения
1, 2, 3, 4.
на вершине стека у нас значение 4.
что бы достать значение 1, то надо стек разобрать в обратном порядке — достаем 4,3,2,1
Я так понял, там какая-то работа со стеком, но не очень допер, что и как реально работает.
Артем, смотри — объясню как умею и понимаю:
когда процессор встречает команду call <адрес>, то он бросает на стек содержимое регистра PC+3, меняет значение PC на <адрес> и продолжает выполнение. т.е. следующая команда будет браться уже из <адрес>. а когда встречается команда ret, то берется значение с вершины стека и пихается в PC, потом опять же идет продолжение выполнения программы.
командами push/pop ты сохраняешь/восстанавливаешь значения регистров в стек/ из стека. и соответственно косвенно изменяешь значение регистра SP (указатель на вершину стека). и если ты запихал в стек допустим 2 регистра, а восстановил 1, то при выполнении команды ret со стека возьмется что? правильно — хрень! и выполнение программы начнеться по направлению неведомой черной дыры :)
вот как-то так
Ну вот синтетический пример реализации GOSUB/RETURN. Ничего полезного не делает, но принцип вроде понятен.
ld a, #01
call SUB ; вызываем процедуру SUB с параметром #01
halt
ld a, #fe
call SUB ; еще раз вызываем процедуру SUB с параметром #FE
di : halt ; стоп машина
; Собственно процедурура SUB
; A - параметр, с которым она играется
SUB
ld b, a
xor a ; наигрались :-)
ret ; возвращаемся туда, откуда пришли
1) Если модуль это просто набор подпрограмм то пишешь их в отдельный файл и include
2) Для массивов удобнее всего использовать индексные регистры ix,iy. С их помощью можно обращаться к элементам в диапазоне +-128 байтов. Ну и смотря что ты с массивом хочешь сделать. Например я в игрухах делаю примерно так:
При вызове doEnemies каждый враг из списка сдвинется вниз на 1 и его энергия уменьшиться на 1 :)
enemiesList
;один враг - 3 байта
;0,1 байты координаты y,x
;2 энергия
;описываем 4 врага
defb 04,07,64
defb 14,21,64
defb 06,11,64
defb 06,04,64
defb 255; 255 - конец списка врагов
doEnemies
;указатель на начало списка врагов
ld ix,enemiesList
;размер структуры
ld bc,3
doOneEnemy
;проверяем не дошли ли мы до конца списка
ld a,(ix+4);один враг 3 байта
cp 255; сравниваем с 255
ret z ;возвращаемся если 255
;сдвигаем каждого врага по y на единичку
ld a,(ix);нулевой байт - у координата
dec a ;уменьшаем на 1
ld (ix),a ;сохраняем
;и уменьшаем энергию на 1
ld a,(ix+2)
dec a ;уменьшаем на 1
ld (ix+2),a ;сохраняем
add ix,bc ;сдвигаем указатель на размер структуры
jr doOneEnemy ;переходим к следующему врагу
А с чего начать? с изучения платформы конечно же. Быстро для Atari и Apple II вряд ли получится.
но на всякий случай — первый пришел, последний ушел.
допустим мы стек бросаем значения
1, 2, 3, 4.
на вершине стека у нас значение 4.
что бы достать значение 1, то надо стек разобрать в обратном порядке — достаем 4,3,2,1
Артем, смотри — объясню как умею и понимаю:
когда процессор встречает команду call <адрес>, то он бросает на стек содержимое регистра PC+3, меняет значение PC на <адрес> и продолжает выполнение. т.е. следующая команда будет браться уже из <адрес>. а когда встречается команда ret, то берется значение с вершины стека и пихается в PC, потом опять же идет продолжение выполнения программы.
командами push/pop ты сохраняешь/восстанавливаешь значения регистров в стек/ из стека. и соответственно косвенно изменяешь значение регистра SP (указатель на вершину стека). и если ты запихал в стек допустим 2 регистра, а восстановил 1, то при выполнении команды ret со стека возьмется что? правильно — хрень! и выполнение программы начнеться по направлению неведомой черной дыры :)
вот как-то так
2) Для массивов удобнее всего использовать индексные регистры ix,iy. С их помощью можно обращаться к элементам в диапазоне +-128 байтов. Ну и смотря что ты с массивом хочешь сделать. Например я в игрухах делаю примерно так:
При вызове doEnemies каждый враг из списка сдвинется вниз на 1 и его энергия уменьшиться на 1 :)