Суббота, 23.11.2024, 04:21
Вы вошли как Гость | Группа "Гости" | RSS

.
 
 
Главная Регистрация Вход
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: Nemesis_c  
how to hacked NHL94 to add 6 buttons support
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ю кнопками. )
Далее останется лишь переназначить новые кнопки.

Исходники хака в аттаче.
Прикрепления: 7598140.zip (14.9 Kb)
 
  • Страница 1 из 1
  • 1
Поиск:


Select language:
English
French
German
Portuguese
Chinese
Nemesis_c, r57shell, Smoke, Lipetsk, GoodBye (aka vfiuchcikicshuusrch) & Segaman © 2024
Хостинг от uCoz