It is currently Sun Dec 10, 2017 5:25 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sat Jan 25, 2014 7:14 am 
Offline
User avatar

Joined: Fri Jan 24, 2014 9:05 am
Posts: 140
Location: Hungary
Hey people! I'm fairly new to 6502 programming in a sense, that I've never actually used proper tools to make anything, hopefully that'll change!
I've been into ROM hacking for quite a while though, and the next step requires me to be here pretty much. I want to modifiy the sound engine made by Capcom, which is used in a ton of their MMC3 games, to include DPCM sample playback. That's not difficult by any means, as I can simply replace one of the less useful effect handlers with my DPCM subroutine. The things is, that this would very likely introduce the glitched controller reads as an artifact.

Since I have a working ROM here by default, I don't want to go all the way of replacing the entire routine for the controller. Can I do something about this and include it in the code for the sample playback?


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 8:12 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19322
Location: NE Indiana, USA (NTSC)
The best way to go about it would involve replacing the routine that actually reads 8 bits from the controller. This wouldn't affect the code that interprets the value read from the controller, which is what I think you're worried about. The best way to hack this in without causing unpredictable slowdown is to read the controller twice, compare the values, and use the values read in the previous frame if they don't match.

Do you have a disassembled listing of the existing controller reading routine, starting where it writes to $4016?


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 8:48 am 
Offline
User avatar

Joined: Fri Jan 24, 2014 9:05 am
Posts: 140
Location: Hungary
tepples wrote:
Do you have a disassembled listing of the existing controller reading routine, starting where it writes to $4016?


Yeah I have a "complete" but mostly undocumented disassembly for Megaman 3 that I found. I hope this is the right thing. I just simply located where it writes to $4016 (and reads from afterwards) and apparently, this is supposed to be it, in bank $1E.
It also seems to be reading the second controller, but I could care less about fixing the input from there.

Code:
L1E_C545:
   ldx #$01
   stx $4016
   dex
   stx $4016
   ldx #$08
L1E_C550:
   lda $4016
   lsr
   rol $14
   lsr
   rol $00
   lda $4017
   lsr
   rol $15
   lsr
   rol $01
   dex
   bne L1E_C550
   lda $00
   ora $14
   sta $14
   lda $01
   ora $15
   sta $15
   ldx #$01
L1E_C573:
   lda $14,x
   tay
   eor $16,x
   and $14,x
   sta $14,x
   sty $16,x
   dex
   bpl L1E_C573
   ldx #$03
L1E_C583:
   lda $14,x
   and #$0c
   cmp #$0c
   beq L1E_C593
   lda $14,x
   and #$03
   cmp #$03
   bne L1E_C599
L1E_C593:
   lda $14,x
   and #$f0
   sta $14,x
L1E_C599:
   dex
   bpl L1E_C583
   rts


Last edited by za909 on Sat Jan 25, 2014 9:27 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 9:17 am 
Offline
Formerly ~J-@D!~
User avatar

Joined: Sun Mar 12, 2006 12:36 am
Posts: 445
Location: Rive nord de Montréal
za909 wrote:
It also seems to be reading the second controller, but I could care less about fixing the input from there.

It does read from controller #2, this is likely some test code left by the developers. It is possible to do mega jumps if one hold a certain button on the controller #2.
You could simply eliminate the code that reads the second controller and act as if no button is ever pressed.


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 9:33 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5885
Location: Canada
I'm kinda wondering, modifying the controller code and adding some DPCM playback commands to the sound engine doesn't sound too tough at all, but how are you going to find space for always-resident DPCM samples? For everything but DPCM you can find space in any bank and swap it in only when needed, but DPCM is always playing! Is this for a romhack, or are you trying to transplant the music engine into your own homebrew? (I'm presuming a romhack since you're asking about modifying the controller routines.) MMC3 does have a banking scheme that suits DPCM well, but if there's vital code running in those banking regions it may be difficult to rearrange.


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 10:04 am 
Offline
User avatar

Joined: Fri Jan 24, 2014 9:05 am
Posts: 140
Location: Hungary
This would be for a romhack basically.

It's quite simple. Bank $1F is always loaded to $E000-$FFFF and never once swapped. There's enough unused junk data here for me to replace, although most of the are in very inconvenient spots, as I can only read from every 64th byte.
There's enough space for a 64 byte sample, a 32 byte sample, and two 289 byte samples (I want these to be really short bass notes, a C and a C# note, so I can cover two octaves with the low pitches, except the upper E and B would be missing)
The game Bee 52 by Codemasters had a very similar approach. I found that slap bass works alright even at such a low quality.

But I could ultimately use drum samples and never worry about the pitch.


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 10:24 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19322
Location: NE Indiana, USA (NTSC)
First I did a couple microoptimizations for space, using the ring counter trick to kill use of X and the CMP trick to read both hardwired controllers (bit 0 of $4016 and $4017) and expansion controllers without needing $00 and $14. Then I used the extra space to add logic that reads the controller twice and uses the previous frame's keypresses if they don't match. I haven't bothered to count the bytes from both versions nor to test it, and I'm open to corrections.
Code:
cur_keys = $16
new_keys = $14
tmp_keys = $00

read_pads_once:    ; Corresponds to L1E_C545
   lda #$01
   sta $4016       ; Load button states into controller's shift register
   sta tmp_keys+1  ; End the loop once the 1 gets shifted up to carry
   lsr a
   sta $4016       ; Finish loading button states
bitloop:
   lda $4016       ; read the controller
   and #$03        ; remove open bus bits
   cmp #$01        ; C = true if either button is pressed
   rol tmp_keys+0
   lda $4017
   and #$03
   cmp #$01
   rol tmp_keys+1  ; C = true if this is the last button
   bcc bitloop     ; look ma, no X!
   rts

read_pads:
   jsr read_pads_once
   lda tmp_keys+0
   sta new_keys+0
   lda tmp_keys+1
   sta new_keys+1
   jsr read_pads_once
   ldx #1
fixloop:
   ; Sanity check 1: Make sure the two reads match
   ; (DPCM double clock compensation)
   ldy cur_keys,x
   lda tmp_keys,x
   cmp new_keys,x
   beq frame_not_glitched
   lda cur_keys,x  ; If glitched, use the previous frame
frame_was_glitched:
   ; At this point, A holds the current buttons and Y holds
   ; the previous buttons

   sta cur_keys,x

   ; Sanity check 2: Left+Right or Up+Down cancel each other out.
   ; Corresponds to L1E_C583
   and #$0C
   cmp #$0C
   bne not_updown
   eor cur_keys,x
   sta cur_keys,x
not_updown:
   lda cur_keys,x
   and #$03
   cmp #$03
   bne not_leftright
   eor cur_keys,x
   sta cur_keys,x
not_leftright:

   ; Calculate newly pressed buttons
   ; Corresponds to L1E_C573
   tya
   eor #$FF
   and cur_keys,x
   sta new_keys,x
   dex
   bpl fixloop
   rts


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 10:37 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
Quote:
The best way to hack this in without causing unpredictable slowdown is to read the controller twice, compare the values, and use the values read in the previous frame if they don't match.

I'm pretty sure most commercial games does it by reading twice, and repeat until you get two consecutive reads that match. In theory it could create major slowdowns, but in practice it doesn't.


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 1:32 pm 
Offline
User avatar

Joined: Fri Jan 24, 2014 9:05 am
Posts: 140
Location: Hungary
Alright guys, sorry for wasting everyone's time. This is clearly not for me. I've spent the last 3 hours fiddling around and nothing worked.
I don't have proper assembly tools, nothing's working on my computer, I can't translate any code to hex properly, and I wish I could punch someone right now. I wouldn't have time to keep doing this hacking stuff anyway. Sorry again.


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 1:36 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
Har come on don't give up romhacking because of this !
You should have started by something simpler, like just palette or graphics hack.


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 3:55 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 804
Location: cypress, texas
za909 wrote:
Alright guys, sorry for wasting everyone's time. This is clearly not for me. I've spent the last 3 hours fiddling around and nothing worked.
I don't have proper assembly tools, nothing's working on my computer, I can't translate any code to hex properly, and I wish I could punch someone right now. I wouldn't have time to keep doing this hacking stuff anyway. Sorry again.
When I'm stumped I pray. : )


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 7:52 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
unregistered wrote:
When I'm stumped I pray. : )

I'm not a religious person, but if I were I wouldn't bother God with my NES ROM Hacking problems while so much bad stuff is happening all around the world!


Top
 Profile  
 
PostPosted: Sat Jan 25, 2014 10:31 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
tokumaru wrote:
unregistered wrote:
When I'm stumped I pray. : )

I'm not a religious person, but if I were I wouldn't bother God with my NES ROM Hacking problems while so much bad stuff is happening all around the world!

God is omnipotent though, so he wouldn't care.

(P.S. I'm not religious either.)

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sun Jan 26, 2014 1:12 am 
Offline
User avatar

Joined: Fri Jan 24, 2014 9:05 am
Posts: 140
Location: Hungary
The problem isn't that I have no idea what I'm doing. I've been hacking for what...4 years now? The problem is that when I wanted to actually practice 6502 asm, I could never find any assembler that worked for me. They're either all DOS or x32 based, so I can't really run them at all, or they're like nesticle, which just intimidate me so bad at first glance. I mean there so much stuff, and I don't know where to begin. All I'd want is just getting straight to the point and start writing my code. I know what the opcodes mean and do (except that I don't get what the difference is between LSR and ROR) and I understand how to control the other peripherals with the CPU.

Hacking now suddenly seems much more difficult than making a new game. I have to make sure I don't change anything, not the stack, not the CPU status before I end my part of the code, and I can't exceed the original amount of data.
In my programs there'd be huge lag anyway because of pushing and pulling every millisecond to make sure the next operations have a clean status register.

I'll come back to this once I have some time.


Top
 Profile  
 
PostPosted: Sun Jan 26, 2014 6:07 am 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1046
Quote:
Hacking now suddenly seems much more difficult than making a new game.

Absolutely, for anything more than the simplest of changes.

Rant edit: Also, making original stuff is a good thing to do. I never learned how to hack. One day I just realized I could after making original stuff for so long. I feel like people who get into hacking first skip a lot of the programming fundamentals and end up banging their head against the wall over really dumb stuff. (Not you specifically, just a thing I see in general.) Whatever game is in question already does things like read the joypad and whatever, so when you hack you avoid learning how to do stuff like that. In fact, many spend more time looking for ways to avoid learning a thing than would take to just learn it. Don't be that guy, please. If the end hacked result and not the knowledge is all you care about, I imagine you won't get it done.

I used to like making free, simple hacks for group hacked-end-result, but I've gradually lost my taste for that.

Quote:
I could never find any assembler that worked for me.

As unregistered said, get asm6: http://home.comcast.net/~olimar/NES/
It's even open source if you happen to not be on Windows.

It'll take a very simple input. Here's a piece of a thing I assembled. Basically just needs a .org statement and your code. Will give you a binary, which you then throw into the rom.

Code:
pointerlo = $02
pointerhi = $03

;Initialize Pointer
;Must find two free bytes of zero page RAM
   .org $FF30
   lda #$01
   sta pointerlo;Unused, reserved for player 2
   lda #$60
   sta pointerhi;Unused, reserved for player 2
   
   jmp $8095


Edit: Ah! And if you're working with a disassembly, yes, you have to get working whatever assembler was used by who made the disassembly or modify the disassembly to work with the assembler YOU choose. Thems the breaks. The latter generally isn't too tough if you actually understand your assembler's syntax.

If you want to practice 6502 code from scratch in a test setting, there's the 6502 macroassembler: http://exifpro.com/utils.html

Edit:
Quote:
(except that I don't get what the difference is between LSR and ROR)

Code:
clc
lda #$01
lsr a
;#$00 is in A


Code:
sec
lda #$01
lsr a
;#$00 is in A


Code:
clc
lda #$01
ror a
;#$00 is in A


Code:
sec
lda #$01
ror a
;#$80 is in A


Ror puts the carry bit into bit 7 of memory (or A). Lsr ignores the carry, and always shifts a zero into bit 7.

Edit: Hopefully the final edit... Tepples, your routine is missing the label "frame_not_glitched", and clocks in at 93 bytes. The original was 88. There might be other problems too, I might look at it more when I have some more time.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group