Разработка и ромхакинг > Ромхакинг и программирование
Геймдев под M68K
<< < (3/10) > >>
Smoke:

--- Цитата: Ti_ ---но если так странно,что не сделали 1+2-ым с 3+4-ым - получилось бы как 2word'a.
--- Конец цитаты ---
По-моему так и сделали. Первые два меняются с двумя последними. Давно уже юзал свап, точно не помню
MetalliC:
Ti_,найди нормальную книгу/PDF по M68K и всё поймешь (жаль сейчас моторола бумажные книжки нашару не высылает, я в свое время успел заполучить парочку ;) )

по прошлому вопросу: bsr и jsr в твоем конкретном случае  - делают одно и то же,
но вообще:
bsr - тупо переход относительно PC с 8-ми 16-ти или 32-х битным (68020+) знаковым смещением
jsr - переход с хреновой кучей возможных адресаций (в том числе и относительно PC c 16-ти битным смещением)


--- Цитата: Ti_ ---да нет, 4eb8 насколько я помню до $8000 только , а если больше то в обратку пойдет. (как moveq)
sega assembler v.3 как раз автоматически делает именно 4eb8 если адрес позволяет, а не 4eb9.
насчет jmp pc - да я не заморачивался просто интересно, что-то две команды одинаковые чтоли?(в RRR есть и те и те)
--- Конец цитаты ---
по моторовской книжке:
4eb8 это jsr (xxxx).w - переход на абсолютный 16-ти битный адрес (не относительный, т.е. без знака)
4eb9 это jsr (xxxx).l - переход на абсолютный 32-х битный адрес
Smoke:

--- Цитата: MetalliC ---4eb8 это jsr (xxxx).w - переход на абсолютный 16-ти битный адрес (не относительный, т.е. без знака)
--- Конец цитаты ---
Ну я ж говорил :)
Ti_:

--- Цитата: MetalliC от 04 Июнь 2010, 01:06:33 ---Ti_,найди нормальную книгу/PDF по M68K и всё поймешь (жаль сейчас моторола бумажные книжки нашару не высылает, я в свое время успел заполучить парочку ;) )

--- Конец цитаты ---
да дело не в книге, команда я и так понимал как работает. хотя что это так происходит, потому что она 16битная не знал.
вопрос был почему она не была использована? были причины какие-то или их компилятор её не знал. (потому что sega assembler определяет 4eb8 , а не 9 , там где возможно)

Добавлено позже:

--- Цитата: MetalliC от 04 Июнь 2010, 01:06:33 ---по прошлому вопросу: bsr и jsr в твоем конкретном случае  - делают одно и то же,
но вообще:

--- Конец цитаты ---
а здесь вопрос стоит так: если они делают одно и тоже, зачем было делать две одинаковые по сути команды?
MetalliC:

--- Цитата: Ti_ ---вопрос был почему она не была использована? были причины какие-то или их компилятор её не знал.
--- Конец цитаты ---
скорее всего банально так программисту захотелось и он в каждой комманде явно указывал .w или .l,
либо была директива компилятору, что для комманд перехода, где явно не указана длина, использовать 16 или 32 бита

--- Цитата: Ti_ ---а здесь вопрос стоит так: если они делают одно и тоже, зачем было делать две одинаковые по сути команды?
--- Конец цитаты ---
еще раз говорю - это две разные комманды

BSR - безусловный переход на подпрограмму относительно PC
15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
0   1   1  0   0   0   0  1 |8бит смещение    |

если смещение = 0 -> смещение следующие 2 байта
если смещение = FF -> смещение следующие 4 байта (68020+)

JSR - безусловный переход на подпрограмму по EA
15 14 13 12 11 10  9  8  7  6  5 4  3  2  1  0
0   1   0  0   1   1   1  0  1  0  mode  register

Адресация   Mode   Register
(An)            010     номер регистра A
(d16,An)      101     номер регистра A
(d8,An,Xn)   110     номер регистра A
(xxx).W       111      000
(xxx).L        111      001
(d16,PC)      111     010
(d8,PC,Xn)   111     011

плюс еще 6 видов адресации для 68020+



Добавлено позже:
ну и главное различие между B-коммандами и J-коммандами:

B-комманды есть по условию или безусловные, но только относительно PC
J-комманды только безусловные, но с кучей разных адресаций
Ti_:
0000 F  False            Z = 1      1000 VC oVerflow Clear   V = 0
0001 T  True             Z = 0      1001 VS oVerflow Set     V = 1
0010 HI HIgh             C + Z = 0  1010 PL PLus             N = 0
0011 LS Low or Same      C + Z = 1  1011 MI MInus            N = 1
0100 CC Carry Clear      C = 0      1100 GE Greater or Equal N (+) V = 0
0101 CS Carry Set        C = 1      1101 LT Less Than        N (+) V = 1
0110 NE Not Equal        Z = 0      1110 GT Greater Than     Z + (N (+) V) = 0
0111 EQ EQual            Z = 1      1111 LE Less or Equal    Z + (N (+) V) = 1

ST d1 вот где видел в dune:
ROM:000008EA                 st      d1

теперь ясно, просто также как и bmi, bpl  и т.д., теперь ток придумать куда их прикручивать раз так редко использовали )

Добавлено позже:

--- Цитата: Smoke от 03 Июнь 2010, 17:35:10 ---Ни разу не встречал

--- Конец цитаты ---
:)

Добавлено позже:

--- Цитата: MetalliC от 04 Июнь 2010, 18:22:12 ---еще раз говорю - это две разные комманды

--- Конец цитаты ---
но именно в этом случае они получаются одинаковые: а именно 4eba (d16,PC)  и bsr.w , но это так получилось не специально,  а из-за архитектуры процессора так я понимаю?
а пихают в ром их программисты от балды и те , и те по вкусу?


ROM:00001E1A                 jsr     sub_0_10D8
ROM:00001E1E                 bra.w   sub_0_1422

4EBA F2BC  6000 F602


ROM:000019E8                 bsr.w   buy_new_car_menu
ROM:000019EC                 jsr     sub_0_1DD0

6100 32D6  4EBA 03E2
GManiac:
Есть ещё повторяющиеся команды, например, ADD.W #imm, Dn и ADDI.W #imm, Dn и другие (SUB, AND, OR). Просто в первом случае #imm - это один из возможных видов операндов для ADD и складываться может только с Dn, а во втором случае #imm - это всегда левый операнд, а правым может быть любой разрешённый вид адресации.
Так что это просто частное совпадение. Откуда оно берётся? Надо понимать хоть немного, как внутри устроен процессор и как он декодирует и выполняет команды.
А если не запрещать некоторые виды адресации, совпадений будет ещё больше. Почему данные случаи не запретили - не знаю.
Почему в одной игре используются оба варианта одной команды - возможно, они встречаются в разных модулях/подпрограммах и их писали разные люди/разные компиляторы. Отсюда и различия.

Scc нужно для вычисления и присвоения логического значения (чтобы обойтись без прыжков, где в одной ветке выдаётся 1, в другой 0). Например, код на паскале

--- Код: ---isEqual := a = b
--- Конец кода ---
можно написать так:

--- Код: ---CMP a, b
SEQ isEqual
--- Конец кода ---
Ti_:

--- Цитата: GManiac от 05 Июнь 2010, 16:56:58 ---Есть ещё повторяющиеся команды, например, ADD.W #imm, Dn и ADDI.W #imm,

--- Конец цитаты ---
ну это не повторяющиеся -  addi.w #1,d0  и add.w d1,d0   ; а add.w #1,d0  вроде как не бывает! (просто в компиляторе все равно как писать- автоматически переделыает add в addi или adda.)

Добавлено позже:

--- Цитата: GManiac от 05 Июнь 2010, 16:56:58 ---Надо понимать хоть немного, как внутри устроен процессор и как он декодирует и выполняет команды.

--- Конец цитаты ---
ну вот и я про это спрашивал.   понимать тут даже не обязательно)
GManiac:

--- Цитата ---ну это не повторяющиеся -  addi.w #1,d0  и add.w d1,d0   ; а add.w #1,d0  вроде как не бывает!
--- Конец цитаты ---
Читать умеем? Я написал:

--- Цитата ---ADD.W #imm, Dn и ADDI.W #imm, Dn
--- Конец цитаты ---
Ещё как бывает такая команда.
Ti_:

--- Цитата: GManiac от 05 Июнь 2010, 18:38:48 ---Читать умеем? Я написал:Ещё как бывает такая команда.

--- Конец цитаты ---
у меня экселя нет чтобы глянуть из твой сосендней темы, может напишешь?
addi.w #1,d0 - 06400001 

add.w #1,d0  - ?
GManiac:
В 68kpm.pdf ведь все опкоды есть.


--- Код: ---ADD <EA>,Dn: 1 1 0 1 Dn 0 Size Mode EARegister
--- Конец кода ---
#imm - это 111100 для Mode + EARregister
Size.w = 01
Dn = d0 = 000
Итого: 1101 000 0 01 111100 = 1101 0000 0111 1100 = D07C
Второе слово - само значение.

Мой дизасм различает эти команды:

--- Код: ---_00000200: D07C 1234                ADD.W     #$1234,D0
_00000204: 0640 1234                ADDI.W    #$1234,D0
--- Конец кода ---
Ti_:

--- Цитата: GManiac от 05 Июнь 2010, 20:47:45 ---Мой дизасм различает эти команды:

--- Конец цитаты ---
вижу, спс.
но если получается , что одинаковые они, то addi.w тоже неспециально делали, а получилось исходя из логики процессора?
но при этом везде используют addi если число+d0. (и компилятор меняет на addi сам)
GManiac:
Наоборот, addi - это команда специально для прибавления числа к операнду любого вида адресации. Т.е.:
#imm, <EA>
С помощью add можно складывать только
<EA>, Dn
Dn, <EA>
операнды, и здесь может получиться частный случай: прибавление числа к регистру Dn:
#imm, Dn
Поэтому "одинаковость" этих команд - просто пересечение частных случаев. Внутренне они декодируются по-разному и, возможно, выполняются по-разному, но суть у них одна.

То же справедливо для BSR.w и JSR (pc).

Что с того, что есть "одинаковые" команды? Нам главное результат. Ну, можно написать move.b #0, <EA>, зачем тогда использовать clr.b <EA>? Для удобства.
А ещё есть трюки вроде:
xor ax,ax (для интелов)
suba a0,a0
и т.д.
Здесь нет ничего необычного.

Добавлено позже:
Компилятор наверно легче настроить так, что когда он видит первым операндом #imm, то он автоматически настривается на команду ADDI. Иначе, чтобы сделать ADD #imm, надо ещё второе условие проверить - чтобы вторым операндом был Dn.
Ti_:

--- Цитата: GManiac от 06 Июнь 2010, 01:33:11 --- Ну, можно написать move.b #0, <EA>, зачем тогда использовать clr.b <EA>?

suba a0,a0
и т.д.
Здесь нет ничего необычного.

--- Конец цитаты ---
есть резон clr. выполнится быстрее по идее) у меня в одной из мануалок с командами еще список по оптимизации скорости смотрел  :)
romanich:
геймдев к сожалению с моей стороны обломался. читаем тут с 11-го пункта.

Исходники проекта.

Ресурсы проекта (спрайты, карты плоскостей).

Управление: U,D,L,R - передвижение, Start - пауза, A - стрельба патронами, B - смена патрона.

В игре 4 фона (меняется через определённое время), боковые стены без повторения!
Ti_:

--- Цитата: Smoke от 03 Июнь 2010, 17:35:10 ---JSR   $4EB8xxxx -- это обычный джамп, где ХХХХ это 2-х байтовый адрес. Прыгать можно от 0 до $FFFF. Редко используется.

--- Конец цитаты ---

--- Цитата: evgeny от 03 Июнь 2010, 18:25:23 ---4eb8 - насколько я помню до $8000 - это прыжок в ROM, а после в RAM.

--- Конец цитаты ---

--- Цитата: MetalliC от 04 Июнь 2010, 01:06:33 ---4eb8 это jsr (xxxx).w - переход на абсолютный 16-ти битный адрес (не относительный, т.е. без знака)

--- Конец цитаты ---
Так я тут тесты провёл вообщем получается что адрес 16 битный, но он знаковый, поэтому прав evgeny.

То есть адрес move.b  d0,($1234).w   это тоже самое что ($00001234).l
Но если адрес move.b  d0,($8900).w           \
                     move.b  d0,($FFFF8900).w     / это = ($FFFF8900).l

hex code -11C0 8900   (FFFF тут нету).   то есть вычитывается из нуля и получается FFFF.

То есть адрес меняется целиком, хоть и 2байта.

Тоже самое все же знают команду moveq ? она в мануале называется 8битной. (move 8-bit immediate), но при этом меняются все 4байта регистра. (т.е. либо 000000xx , либо ffffffxx)

И разрабы многих игр как раз использовали 16битную, получая халявный доступ к RAM , начиная с
$FF8000, то есть 'читерили', потому что другие разрабы этого не знали(то есть не во всех играх есть.)   (и поэтому в loader'e HardwareMan'а  два сегмента ram создает)

Но при этом им прихидолись в область FF0000-FF8000  залезать по 32битной адресации.

но в RRR поступили умнее - там просто закинули в a4=FF8000 ( и получили доступ ко всей памяти, 16-битный, т.е. от -8000 до +8000 от-но (a4) , но это уже от-ная адресация).


Но, я тут по-другому вопросу вообщем, как загонять ram в исходник? т.е. создать рам + c00000+a00000 (чтобы получить доступ к меткам "lea VDP " и т.д.). Или как это надо делать?  (просто как задать меткам адрес?)
Я пока не пробовал, ну чтобы файл не вырос до 16мегабайт, т.е. если писать "ds.b" как в IDA? (или в компиляторе обрезать как-то размер?)
Smoke:

--- Цитата: Ti_ ---Но, я тут по-другому вопросу вообщем, как загонять ram в исходник? т.е. создать рам + c00000+a00000 (чтобы получить доступ к меткам "lea VDP " и т.д.). Или как это надо делать?  (просто как задать меткам адрес?)Я пока не пробовал, ну чтобы файл не вырос до 16мегабайт, т.е. если писать "ds.b" как в IDA? (или в компиляторе обрезать как-то размер?)
--- Конец цитаты ---
А собственно зачем это? Нужно что-то забить в RAM в самой начале загрузки рома что ли? По сути, я просто пишу абс. смещение и все, типа
move.w   #$855E, $C00004
Ti_:

--- Цитата: Smoke от 14 Июль 2010, 00:24:54 ---А собственно зачем это? Нужно что-то забить в RAM в самой начале загрузки рома что ли? По сути, я просто пишу абс. смещение и все, типа
move.w   #$855E, $C00004

--- Конец цитаты ---
move.w  d0, car1_X_speed      (чтобы сорс читабельный был)

что-то в этом роде:
 org $FFС200
car1_X_speed:
 ds.b 1         
car2_X_speed:
 ds.b 1

+в дальнейшем ещё из адреса метки "вычитать" адрес метки. (я так у себя сделал чтобы разницу в архивах считал асм, а они инкбинами лежат). 
типа так:

--- Код: --- org $20000
SOUND_MUSIC
 dc.w sounds-SOUND_MUSIC
 dc.b 6
 dc.b 0

 dc.l musictrack1-SOUND_MUSIC
 dc.l musictrack2-SOUND_MUSIC
 dc.l musictrack3-SOUND_MUSIC
 dc.l musictrack4-SOUND_MUSIC
 dc.l musictrack5-SOUND_MUSIC
 dc.l musictrack6-SOUND_MUSIC
musictrack1
 incbin music\mtrack1.smg
musictrack2
 incbin music\mtrack2.smg
musictrack3
 incbin music\mtrack3.smg
musictrack4
 incbin music\mtrack4.smg
musictrack5
 incbin music\mtrack5.smg
musictrack6
 incbin music\mtrack6.smg

sounds
 dc.w $2A
 dc.l sound0-SOUND_MUSIC
 dc.w sound1-sound0
 dc.w 0
 dc.l 0
 dc.l sound1-SOUND_MUSIC
 dc.w sound2-sound1
 dc.w 0
 dc.l 0
--- Конец кода ---


А тут я думал задать:

 org $FF8000
M
 ds.b 1


если прокатит-загнать ещё и относительные в RAM через разницу меток,

move.w d0, car1_X_speed-M(a4)         =  $4200(a4)
GManiac:

--- Цитата ---То есть адрес move.b  d0,($1234).w   это тоже самое что ($00001234).l
Но если адрес move.b  d0,($8900).w           \
                     move.b  d0,($FFFF8900).w     / это = ($FFFF8900).l

hex code -11C0 8900   (FFFF тут нету).   то есть вычитывается из нуля и получается FFFF.

То есть адрес меняется целиком, хоть и 2байта.

Тоже самое все же знают команду moveq ? она в мануале называется 8битной. (move 8-bit immediate), но при этом меняются все 4байта регистра. (т.е. либо 000000xx , либо ffffffxx)
--- Конец цитаты ---
В MOTOROLA 68000 FAMILY Programmer’s Reference Manual обо всём этом написано. Даже схемы нарисованы, какая часть адреса берётся и когда он знакорасширяется. В частности, конечный адрес всегда 4-хбайтный, а воздействие на адресный регистр всегда влияет на весь регистр, о чём там часто написано. Т.е. если адрес в команде двухбайтный (например, MOVEA), он знакорасширяется до 4 байт и пишется в адресный регистр.

То же про MOVEQ, всё там написано:

--- Цитата ---Description: Moves a byte of immediate data to a 32-bit data register. The data in an 8-bit
field within the operation word is sign- extended to a long operand in the data register
as it is transferred.
--- Конец цитаты ---



--- Цитата ---
--- Цитата ---Но, я тут по-другому вопросу вообщем, как загонять ram в исходник? т.е. создать рам + c00000+a00000 (чтобы получить доступ к меткам "lea VDP " и т.д.). Или как это надо делать?  (просто как задать меткам адрес?)
--- Конец цитаты ---

--- Конец цитаты ---
Директива equ.
Ti_:

--- Цитата: GManiac от 14 Июль 2010, 01:30:44 ---Т.е. если адрес в команде двухбайтный (например, MOVEA), он знакорасширяется до 4 байт и пишется в адресный регистр.

Директива equ.

--- Конец цитаты ---
ясно, спасибо.

но то, все равно там если глянуть часть адресов можно было сделать, но не сделали через 2байта.
(может компилятор такой был?)
потом если посмотреть многие разрабы старались большую часть игры поставить в ram начиная с >ff8000  и там больше всего адресов находится , а другие делали просто подряд от начала ram.
Навигация
Главная страница сообщений
Следующая страница
Предыдущая страница

Перейти к полной версии