Nemesis_c | Дата: Четверг, 01.09.2011, 08:05 | Сообщение # 1 |
Сообщений: 1148 Статус: Offline
| Взято с сайта http://gendev.spritesmind.net/
Disasm disasm и еще раз disasm!
Чтобы добавить поддержку 6 кнопочного джойстика, я должен был найти метод чтения кнопок джойстика. Спасибо IDA и моему скрипту M.IDA, с ними все очень просто : загрузите game.bin в IDA, укажите 68k, запустите M.IDA IDC script, нажмите G и перейдите на 0xA10003.
Вот, пожалуйста: IDA говорит вам, откуда вызывается 0xA10003 (DATA1) - прыгаем по сылкам, чтобы найти нужный метод. On NHL94, I have 3 methods which make a call to 0xA10003 0xF6D5E => из-за того что здесь записываются байты в DATA2 & CTRL2, я сразу понял что это обычный детектор (х.з.) 0x1A430 => это мог быть нужный метод, но я заметил несколько бранчей (bsr) на 0x1A498, внутрь третьего метода 0x1A470 => то что нам нужно:
Code move.b #0,(a0) nop nop move.b (a0),d0 ; d0 = 00SA00DU move.b #$40,(a0) ; '@' nop nop move.b (a0),d1 ; d1 = 01CBRLDU Видим чтение джойстика..
Постойте... я не могу найти это в <имя вашей игры> !
Добро пожаловать в кошмар ASM. IDA очень хороша, но разработчики могут использовать различные трюки, например для оптимизации размера рома.. () Один из таких трюков data-following-call (или как он там называется)...
Code jsr unk_11B92 ; tiles info is following function call ori.b #5,d6 ori.b #$1E,d0 moveq #6,d1
Что за хрень в этом куске кода?
Если вы посмотрите на функцию unk_11B92, вы заметите странную вещь movea.l 4(sp),a1 - это значит a1 = адресу кода следующим за вызовом функции ( ori.b #5,d6 в нашем случае) С помощью участников форума spritesmind я наконец-то понял, как перевести этот код :
Code jsr loc_11B92 ; конфиг таилов идет за вызовом функции ; --------------------------------------------------------------------------- dc.w 6 dc.b $BD ; � dc.b 5 dc.b 0 dc.b 0 dc.b $70 ; p dc.b $1E ; --------------------------------------------------------------------------- moveq #6,d1
Почему это кошмар? Потому, что IDA автоматически преобразует все в качестве кода, и поэтому может распознать прыжки или бранчи там, где их нет на самом деле. Затем IDA начинает дизасмить те места, куда ссылаются ложные прыжки и в итоге мы получаем кучу неверного кода.
Другой запутанный метод - это массив со ссылками (прыжками). Это удобно при для разработчиков, но IDA или другой дизассемблер этого не поймет. Хорошая новость - такие массивы легко находятся: вбейте в поиск код jmp (a0) Конечно, вы все равно должны понять, как инициируется a0. Если вы скажете IDA продолжить анализ этих данных, вы увидите много нового кода... По адресу 0x11A78, вы найдете пример массива прыжков:
Code move.b (a1)+,d0 ext.w d0 bgt.w loc_11A94 ; if MSB=0 neg.w d0 asl.w #2,d0 movea.l #off_11AF4,a2 movea.l (a2,d0.w),a2 jsr (a2) bra.w loc_11ADC
a2 является указателем на массив прыжков, вы можете быть уверены, вы найдете множество указателей на 0x11AF4:
Code off_11AF4: dc.l locRTS dc.l sub_11B28 dc.l sub_11B3C dc.l sub_11B4C dc.l loc_11B5A dc.l loc_11B68 dc.l loc_11B76 dc.l loc_11B84 dc.l loc_11B18
вы должны перевести все это в data long.
Добавляем поддержку 6 кнопок
Chilly Willy's code:
Code | get current pad value | entry: a0 = pad control port | exit: d2 = pad value (0 0 0 1 M X Y Z S A C B R L D U) or (0 0 0 0 0 0 0 0 S A C B R L D U) get_pad: bsr.b get_input /* - 0 s a 0 0 d u - 1 c b r l d u */ move.w d0,d1 andi.w #0x0C00,d0 bne.b no_pad bsr.b get_input /* - 0 s a 0 0 d u - 1 c b r l d u */ bsr.b get_input /* - 0 s a 0 0 0 0 - 1 c b m x y z */ move.w d0,d2 bsr.b get_input /* - 0 s a 1 1 1 1 - 1 c b r l d u */ andi.w #0x0F00,d0 /* 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 */ cmpi.w #0x0F00,d0 beq.b common /* six button pad */ move.w #0x010F,d2 /* three button pad */ common: lsl.b #4,d2 /* - 0 s a 0 0 0 0 m x y z 0 0 0 0 */ lsl.w #4,d2 /* 0 0 0 0 m x y z 0 0 0 0 0 0 0 0 */ andi.w #0x303F,d1 /* 0 0 s a 0 0 0 0 0 0 c b r l d u */ move.b d1,d2 /* 0 0 0 0 m x y z 0 0 c b r l d u */ lsr.w #6,d1 /* 0 0 0 0 0 0 0 0 s a 0 0 0 0 0 0 */ or.w d1,d2 /* 0 0 0 0 m x y z s a c b r l d u */ eori.w #0x1FFF,d2 /* 0 0 0 1 M X Y Z S A C B R L D U */ rts
no_pad: move.w #0xF000,d2 rts
| read single phase from controller get_input: move.b #0x00,(a0) nop nop move.b (a0),d0 move.b #0x40,(a0) lsl.w #8,d0 move.b (a0),d0 rts
Теперь я добавлю "6 кнопочный джой" в 0x1A49A 3 кнопочный только от 0x1A49A до 0x1A4AE - это позволит мне вставить код Chilly Willy. Итак, я добавлю код в свободное место а затем вызову его. Я заменил оригинальный код на jsr <my_6button_method> а все что осталось забил nop'ами. В конце моего кода нужно поставить RTS (первый раз я забыл об этом) В итоге ром заработал с 6ю кнопками. ) Далее останется лишь переназначить новые кнопки.
Исходники хака в аттаче.
|
|
| |