6502 assembler, .org directive

MOS Technology / Commodore / Apple II / NES etc.

Moderator: Lavr

spacebiker
Junior
Posts: 5
Joined: 29 Mar 2020 02:01

6502 assembler, .org directive

Post by spacebiker »

Всех приветствую.
Возникла идея написания собственного транслятора ассемблера для ines формата. В процессе написания осознал, что не совсем понимаю, как действует директива .org
В документации к компилятору сказано:
.org
Set the location of the program counter.
В таком случае, после .org транслятор должен начинать писать инструкции с заданного адреса. Рассмотрим такой код:

Code: Select all

  .bank 0
  .org $0020

LABEL:
	LDA #$FF
	STA $CC
   JMP LABEL
Компилируем с помощью NESASM и получаем соответственно:
00000000 4E 45 53 1A 01 01 01 00 00 00 00 00 00 00 00 00
00000010 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000020 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00000030 A9 FF 8D CC 00 4C 20 00 FF FF FF FF FF FF FF FF
Меняем .org $0020 на .org $C000 и получаем:
00000000 4E 45 53 1A 01 01 01 00 00 00 00 00 00 00 00 00
00000010 A9 FF 8D CC 00 4C 00 C0 FF FF FF FF FF FF FF FF
Видим, что запись происходит с $0000, но при этом адрес метки поменялся на $C000.
Разъясните, пожалуйста, что происходит и как это учитывать при написании транслятора
User avatar
Icer
Senior
Posts: 163
Joined: 21 Aug 2018 07:39
Location: Кемеровская обл.

Re: 6502 assembler, .org directive

Post by Icer »

Транслятор сделал "бинарник" и что бы запустить код нужно переместить его по адресу указанному директивой .org

Это вроде называется косвенной трансляцией, ведь нужные адреса в памяти могут быть заняты самим ассемблером
т.е. должна быть еще какая-то директива с параметром указывающий косвенный адрес

p.s. похоже "косвенная трансляция" это моя фантазия, по крайней мере гугл не в курсе, но посыл надеюсь ясен.
spacebiker
Junior
Posts: 5
Joined: 29 Mar 2020 02:01

Re: 6502 assembler, .org directive

Post by spacebiker »

Icer wrote:Транслятор сделал "бинарник" и что бы запустить код нужно переместить его по адресу указанному директивой .org

Это вроде называется косвенной трансляцией, ведь нужные адреса в памяти могут быть заняты самим ассемблером
т.е. должна быть еще какая-то директива с параметром указывающий косвенный адрес

p.s. похоже "косвенная трансляция" это моя фантазия, по крайней мере гугл не в курсе, но посыл надеюсь ясен.
Спасибо за пояснение!
Правда пару вещей всё равно понять не могу... Транслятор ведёт себя очень странно. Для всех адресов < $00FF транслятор делает сдвиг прямо в hex-коде. Для адреса $A000, например, сдвиг не происходит, для $B000 - происходит, но пишет в $1000, хотя адрес метки нужный. Для $C000 не происходит, равно как и для $C001...
Я правильно понимаю, в NES архитектурно код находится по адресу $C000? Т.е транслятор пишет в 0000 считая, что это $C000 в памяти консоли? Всё, тогда всё ясно: в трансляторе $C000 стоит как начальный адрес, тогда сдвиг на адрес $N - это ($N - $C000)
spacebiker
Junior
Posts: 5
Joined: 29 Mar 2020 02:01

Re: 6502 assembler, .org directive

Post by spacebiker »

Получаем такую картину:
пусть есть .org N
1) Если N >= $C000, то в бинарнике сдвиг происходит на позицию (N - $C000), а в памяти консоли это будет соответственно адрес N
2) Если N < $C000, то в бинарнике сдвиг идёт просто на N, а в памяти консоли это будет $C000 + N
User avatar
Icer
Senior
Posts: 163
Joined: 21 Aug 2018 07:39
Location: Кемеровская обл.

Re: 6502 assembler, .org directive

Post by Icer »

Вероятно непонятки возникают из-за особенностей архитектуры nes. Существует не нулевой шанс, что вы уже в процессе поисков встречали сайт MiGeRA и все же по рекомендую:
http://dendy.migera.ru/nes/g01.html
spacebiker
Junior
Posts: 5
Joined: 29 Mar 2020 02:01

Re: 6502 assembler, .org directive

Post by spacebiker »

Icer wrote:Вероятно непонятки возникают из-за особенностей архитектуры nes. Существует не нулевой шанс, что вы уже в процессе поисков встречали сайт MiGeRA и все же по рекомендую:
http://dendy.migera.ru/nes/g01.html
Спасибо!
spacebiker
Junior
Posts: 5
Joined: 29 Mar 2020 02:01

Re: 6502 assembler, .org directive

Post by spacebiker »

Как реализовывать .org стало ясно, но вот вместе с .bank происходят странные вещи. Вот например, в типичном примере игры на NES есть строчки:

Code: Select all

.bank 2
.org $E000
и далее начинается резервирование данных.
Проблемы тут сразу две:
Во-первых, данные, следующие ниже, имеют совершенно иные адреса в коде, $0210, например.
Во-вторых, вот этот $E000 - очень странный адрес. В доках к транслятору сказано:
.bank
Select a 8 KB ROM bank (0-127) and reset the location counter to the latest known position in this bank.
Но! 8кб заканчивается на $2000, т.е .bank 2 должен быть в адресах $4000-$6000, а если счётчик начинается с нуля, то $E000 всё равно больше 8кб.
В одном туториале нашёл такое:
$8000 - $FFF9 is the PRG-ROM, which basically means it's where all of your programming data will be located in, 32K of it. Larger programs can perform bank switching to execute other code.
Но даже в случае, если каждый банк имеет размер 32кб, а адресация, вероятно, идёт с нуля, всё равно не сходится: $E000 ведь больше, чем 32кб. А если счётчик идёт не с нуля, то нулевой банк должен заканчиваться на $8000, а вот первый уже выходит за границы памяти - $10000.
Кажется, я упускаю что-то очень простое, но при этом очень важное
User avatar
Icer
Senior
Posts: 163
Joined: 21 Aug 2018 07:39
Location: Кемеровская обл.

Re: 6502 assembler, .org directive

Post by Icer »

ROM находится с $8000, младшие банки находятся в старших адресах
$8000-$BFFF 16k PRG-ROM (1)
$C000-$FFFF 16k PRG-ROM (0)
табличка по ссылке которую приводил выше