Для 6502 не помешает ссылка на перевод система команд 6502.
А с чего начать? с изучения платформы конечно же. Быстро для Atari и Apple II вряд ли получится.
  • avatar sq
  • 4
Вообще не понимаю, как это работает. Как-то на основе машины времени, я полагаю?
  • avatar elfh
  • 4
Только в Emuzwin можно прогу назад отматывать. Бесценно для дебага.
Про музыку начинал писать Kakos_nonos , надо трясти продолжение :-)
Вам всем спасибо, что такие посты пишите
  • avatar diver4d
  • 1
Спасибо! Надеюсь, будет дополняться топик и прирастать!
В принципе, очевидная тонкость для меня, но возможно кому-то будет полезно. Спасибо!
Да, знаю, конечно)
  • avatar ShaMAN
  • 0
примечание: на стек идут только регистровые пары и данные по 2 байта
Йей! Спасибо!
  • avatar ShaMAN
  • 1
принцип работы стека знаешь? надеюсь, что знаешь)
но на всякий случай — первый пришел, последний ушел.
допустим мы стек бросаем значения
1, 2, 3, 4.
на вершине стека у нас значение 4.
что бы достать значение 1, то надо стек разобрать в обратном порядке — достаем 4,3,2,1
  • avatar ShaMAN
  • 1
я вот для этого написал
Я так понял, там какая-то работа со стеком, но не очень допер, что и как реально работает.

Артем, смотри — объясню как умею и понимаю:
когда процессор встречает команду call <адрес>, то он бросает на стек содержимое регистра PC+3, меняет значение PC на <адрес> и продолжает выполнение. т.е. следующая команда будет браться уже из <адрес>. а когда встречается команда ret, то берется значение с вершины стека и пихается в PC, потом опять же идет продолжение выполнения программы.
командами push/pop ты сохраняешь/восстанавливаешь значения регистров в стек/ из стека. и соответственно косвенно изменяешь значение регистра SP (указатель на вершину стека). и если ты запихал в стек допустим 2 регистра, а восстановил 1, то при выполнении команды ret со стека возьмется что? правильно — хрень! и выполнение программы начнеться по направлению неведомой черной дыры :)
вот как-то так
  • avatar nyuk
  • 1
Ну это не абсолют же. Можно хоронить регистры в самой процедуре. Можно вообще забить. По-всякому оно бывает.
Да, это даже не массив и список структур :) Только у меня последний враг не обработается, ну не суть :)
  • avatar ShaMAN
  • 0
только надо добавить, что в начале процедуры надо push все регистры которые портишь, а перед выхором pop их обратно
  • avatar nyuk
  • 2
(SUB нельзя использовать в качестве имени метки)
  • avatar nyuk
  • 2
Ну вот синтетический пример реализации 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	; возвращаемся туда, откуда пришли
Label + defb — это, я так понимаю, и есть массив. О как! УДобно, спассибо!
Блин, всё так просто :D
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 ;переходим к следующему врагу