It is currently Mon Nov 12, 2018 8:02 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Wed Oct 17, 2018 5:49 pm 
Offline
User avatar

Joined: Wed May 23, 2012 11:30 pm
Posts: 44
Are there any M68k assemblers out there that allow for patching of a ROM using "org" like what currently exists for SNES? I have done some searching and cannot find anything like this. Trying my hand at a SFII: Champion Edition hack for CPS1 and it would be way easier to do it this way than manually transcribe my new code into hex. Thanks.


Top
 Profile  
 
PostPosted: Thu Oct 18, 2018 3:35 pm 
Offline

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 692
ORG does normally tell the assembler to assemble the following instructions as if they located at a given memory address. It doesn't actually take care of moving data to that address, and least mixing it with an existing binary.
What you are looking for might be something like "INCBIN filename,fileoffset,length". You could also make a macro for it, where you specify only the end address in memory, and let the macro load data up to that address, with automatically computed fileoffset and length values.


Top
 Profile  
 
PostPosted: Thu Oct 18, 2018 3:52 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3676
Location: Mountain View, CA
I'm not 68K-savvy, but I'm not aware of anything like this "for the SNES" with one exception: byuu's bass. I literally haven't seen such a feature in any other assembler in my entire life.

Normally what you're expected to do is disassemble existing code, do the modifications, and reassemble it. For stuff unrelated to the disassembled portion, it's easiest to incbin (or whatever the equivalent is in the assembler) those portions, making sure they "properly line up" (address-wise). It's up to you to make sure things work properly (ex. if code in the incbin'd section does something like jmp {some-address-in-the-disassembled-portion}, and you've moved where that code actually is due to your changes, you've now created quite a bad bug).


Top
 Profile  
 
PostPosted: Thu Oct 18, 2018 4:12 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10959
Location: Rio de Janeiro - Brazil
nocash wrote:
ORG does normally tell the assembler to assemble the following instructions as if they located at a given memory address. It doesn't actually take care of moving data to that address, and least mixing it with an existing binary.

Normally, the first ORG just sets the address, but subsequent ORGs will pad until the specified addresses.

Quote:
What you are looking for might be something like "INCBIN filename,fileoffset,length". You could also make a macro for it, where you specify only the end address in memory, and let the macro load data up to that address, with automatically computed fileoffset and length values.

There are assemblers that allow overlapping though, but I'm not familiar with 68000 tools.


Top
 Profile  
 
PostPosted: Thu Oct 18, 2018 5:25 pm 
Offline
User avatar

Joined: Wed May 23, 2012 11:30 pm
Posts: 44
Ah ok. It was some variant of xkas that I was using. Didn't realize this wasn't a standard feature. Doing a full disassembly is kinda out of the question because that would probably take me ten years, so I guess I'll do this the hard way. Thanks for the info.


Top
 Profile  
 
PostPosted: Thu Oct 18, 2018 5:37 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20760
Location: NE Indiana, USA (NTSC)
Sverker wrote:
Ah ok. It was some variant of xkas that I was using.

And bass is the follow-up to xkas.

rgblink in RGBDS (Game Boy assembler) also supports an overlay file, used to fill regions where nothing got assembled.

Quote:
Doing a full disassembly is kinda out of the question because that would probably take me ten years, so I guess I'll do this the hard way. Thanks for the info.

The other way is what I did with my mapper hack of Solar Wars: hack something up with offset and length arguments to .incbin.


Top
 Profile  
 
PostPosted: Thu Oct 18, 2018 5:46 pm 
Offline
User avatar

Joined: Wed May 23, 2012 11:30 pm
Posts: 44
I'm thinking now I might just rig up a quick and dirty console app to keep track of everything for me on this specific project. Maybe not the most elegant solution but what can you do.


Top
 Profile  
 
PostPosted: Sat Oct 20, 2018 12:36 am 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 621
This isn't anything amazing in terms of assembler, any half decent more than 2 pass assembler should do it. The complication you will have with 68K assemblers is they are very much from the linker era, so you might have to get the linker to do the dirty work. But any assembler that has *= for code starting should do what you want. I would just try assemblers to see. Easy68K or sn68k would be my first port of call.

If they really won't do it, you could use TASS64 as a preprocessor.

Assemble your code to a bin file. then you can just do

*=$000000
.binary "yourbinaryhere.bin"

*=$XXXX
.binary "patch.bin"
*=$YYYYY
.binary "patch2.bin"

etc
you will want to set TASS64 to binary output and 65816 mode so you get the full 16MB address space, assuming your bin file is less than 16MB.
64tass -a -x -b -f
if you need to put it to ROM the --s-record format might be useful to you as that is the Motorola S-record used by burners and downloaders.

PS if you want this for SNES 64tass has full 65816 support and if you want it for NES full N6502 support as well.


Top
 Profile  
 
PostPosted: Sat Oct 20, 2018 2:24 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6947
Location: Canada
koitsu wrote:
I'm not 68K-savvy, but I'm not aware of anything like this "for the SNES" with one exception: byuu's bass. I literally haven't seen such a feature in any other assembler in my entire life.

I recently learned that cc65 has an overwrite feature for this purpose. (Doesn't help OP of course.)


Top
 Profile  
 
PostPosted: Sat Oct 20, 2018 2:37 am 
Offline

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 692
tokumaru wrote:
Normally, the first ORG just sets the address, but subsequent ORGs will pad until the specified addresses.

Yeah, I`ve also seen source files for some assemblers using "ORG address" or "*=address" for automatic padding. I don't know if that's actually the widespread normal case, or a misconception, or both ; )

For padding to address, I would use things like DUP, FILL, DEFS, REPT, with "address-$" or "address-*" as length. Being able to use ORG for padding might seem useful at first glance, but that automated padding does screw up ability to relocate code manually.

For example, for a NES game, if you relocate code from ROM to RAM, you'd have "ORG 8000h" (rom) containing your relocation function, followed by "ORG 200h" (ram) containing the relocated code, plus "ORG reloc_src+reloc_len" to resume ROM addressing for further ROM code & exception vectors. How would that work on assemblers that apply padding on ORG?


Top
 Profile  
 
PostPosted: Sat Oct 20, 2018 3:28 am 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 621
that sounds like a crazy system, if ORG sets the address of assembly, what set the PC address?

you have
Code:
*=$8000 ; this set the assembly address to 8000
to change the final target of the assembly, so code that you copy and execute somewhere else you change the assembly PC but not the current PC
.logical $200
start
lda Start+5
sta $d020
rts
.byte 00
.here
so Start+5 = $205 however the code will be stored at $8000 in the output file.

To make a standard NES ROM starting at $8000 bin file you would do
Code:
*=$0000 ; assembly set to output $0
.logical $8000 ; assemble as if the code is at $8000
..your code here
.here
if you have multiple banks at $8000 and a fixed bank at $c000 store in ram as 16K 8K 8K 8K overlay
Code:
*=$0000
.logical $8000
16K of code here
.here
;Bank1 ; $4000 @$8000
.logical $8000
upto 8K here
.align $c000
.here
;Bank 2 ; $6000 @$8000
.logical $8000
upto 8K here
.align $c000
.here
;Bank 3 ; $8000 @$8000
.logical $8000
upto 8K here
.align $c000
.here
However I would recommend using sections and collecting them to form your actual code.

You then have the .virtual case which lets you put a struct or anything else that doesn't actually modify memory at a fixed location. For example you might want to map PPU registers this way.
Code:
.virtual $2000
.block PPU
 CTRL .byte ?
 MASK .byte ?
 STATUS .byte ?
 OAMADDR .byte ?
 OAMDATA .byte ?
 PPUSCROLL .byte ?
 PPUADDR .byte ?
 PPUDATA .byte ?
 OAMDMA .byte ?
.bend
.endv

this way you don't have to actually move the assemble address or logical address and can just place a virtual move so it won't appear in the output memory map. However you can do
STA PPU.MASK and it will put $2001 for you.
The true power of Virtual is it will take an expression so
Code:
.virtual #1,s
p1  .addr ?
tmp .byte ?
.endv
lda (p1),y will assemble to lda ($01,s),y
lda (tmp) will assemble to lda $03,s


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

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