Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Merlin32 and Negative DS Pseudo Op

78 views
Skip to first unread message

Hugh Hood

unread,
Oct 10, 2021, 2:50:46 PM10/10/21
to
I'm doing some continually updated patches to an existing binary file
(ProDOS - 8 bit) where I use the Merlin32 'PUTBIN' pseudo op to place
the existing binary at the current object pointer, add my new code to
the end, and then assemble the source to generate the patched binary.
Simple enough.

For example:

Start
PUTBIN FILETOPATCH ; existing binary file

NewCode
LDA {etc} ; all the new and patching code

CodeEnd
SAV PATCHEDFILE ;


I've been manually editing the first three (3) bytes of the existing
binary so that its first instruction is to JMP to NewCode. That's not
very difficult nor time consuming, but I'd like to make it all more
automatic, if possible.

Ideally, I would use a Pseudo Op at the end of the source code to move
back the object pointer to the very beginning and overwrite the first
three (3) bytes of the PUTBIN'ed file with the necessary JMP to NewCode.

The Merlin 16 manual mentions using the 'DS' pseudo op with a negative
number (e.g. DS-1) to "back up the object and address pointers".
Frankly, I'm not sure if even that would accomplish what I'd like, but I
do know that in Merlin32 1.0 using 'DS-1' just generates an 'UNKNOWN' error.

Can anyone set me on the straight path to some method that would work?

I'll even gladly accept 'no, that can't be done' so that I won't spend
any more time on it, and just keep manually patching those first three
(3) bytes.

Thanks.




Hugh Hood

Antoine Vignau

unread,
Oct 22, 2021, 2:37:41 PM10/22/21
to
Hi Hugh,
I do not understand what you want to achieve with the negative DS.
On Merlin 16 and 32, DS -1 will reserve $65535 bytes of memory.
On Merlin 16 and 32, DS *-1 will reserve current_address - 1 bytes of memory.

What am I missing here? If you want to link to an address in the putbin, you can do the following:

myCode putbin toto.bin
myLabel = *

patchAbove
lda #$BD
sta myLabel-3

Cheers,
Antoine

fadden

unread,
Oct 23, 2021, 11:03:46 AM10/23/21
to
I believe what he's trying to do is patch the binary included with PUTBIN with the assembler itself.

With an assembler written by C64 people you can do this, because they have separate notions of "physical" and "logical" program counters within the assembler. For example, in 64tass if you do this:

* = $1000
lda $1234

* = $1001
.word $4567
rts

The output is:

00000000: ad67 4560 .gE`

Merlin32 only has a "logical" PC, so it assembles the same code to:

00000000: ad34 1267 4560 .4.gE`

The C64 assemblers place everything into a 64KB bank. If the output is discontiguous, you'll get empty gaps in the output file. It will even wrap around at the end of the bank, so the stuff you output at the end of the source file ends up at the start of the binary. (https://sourceforge.net/p/tass64/bugs/59/)

Once I understood this, certain aspects of 64tass and ACME made a lot more sense. I'm not aware of an Apple II assembler that had the notion of separate PCs, though the old "OBJ" directive could have been used this way.

Kent Dickey

unread,
Oct 23, 2021, 12:17:41 PM10/23/21
to
In article <e4fe03ff-6504-4557...@googlegroups.com>,
EDASM worked differently and I think you could rewrite earlier
instructions by storing instructions directly in memory at the OBJ
addresses. EDASM was really slow and hard to use, so it wasn't popular
(at least the DOS 3.3 version was slow).

Kent

fadden

unread,
Oct 23, 2021, 1:17:36 PM10/23/21
to
On Saturday, October 23, 2021 at 9:17:41 AM UTC-7, Kent Dickey wrote:
> EDASM worked differently and I think you could rewrite earlier
> instructions by storing instructions directly in memory at the OBJ
> addresses. EDASM was really slow and hard to use, so it wasn't popular
> (at least the DOS 3.3 version was slow).

From the "Apple 6502 Assembler/Editor" manual (the scan of which doesn't seem to include a page with a copyright date on it):

"The OBJ directive has been included for compatibility with a previous version of this Assembler, in which it was used to specify the memory address of the output object file, which now can only be written on the output diskette. This directive is reserved for possible future enhancement of the Assembler/Editor system."

So I think the DOS Toolkit version of EDASM didn't really support it either.

Hugh Hood

unread,
Oct 23, 2021, 2:43:59 PM10/23/21
to
On 10/23/2021 10:03 AM, fadden wrote:

>
> I believe what he's trying to do is patch the binary included with
> PUTBIN with the assembler itself.
>

Exactly! Thanks for boiling that down to one succinct sentence for me.

Thanks, fellas, for chiming in with the information and your thoughts
about this. I don't mind patching the object code after the assembler
generates it, but I didn't want to overlook an easier way to do it all
from within the assembler.

I've seen many clever techniques using assembler math and '*' operations
here and thought I'd give it a shot. Thanks.




Hugh Hood

Oliver Schmidt

unread,
Oct 24, 2021, 4:23:43 AM10/24/21
to
Hi Hugh,

>> I believe what he's trying to do is patch the binary included with
>> PUTBIN with the assembler itself.

> Exactly! Thanks for boiling that down to one succinct sentence for me.

The ld65 linker supports 'overwrite' segments for that very purpose.
https://cc65.github.io/doc/ld65.html#ss5.4 says:

Perhaps you are modifying an OS ROM that has its public subroutines at
fixed, well-known addresses, and you want to prevent them from shifting to
other locations in memory if your changed code takes less space. Or you are
updating a block of code available in binary-only form with fixes that are
scattered in various places. Generally, whenever you want to minimize
disturbance to an existing code brought on by your updates, OVERWRITE
segments are worth considering.

Regards,
Oliver




0 new messages