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

6502 assembler for Unix with multiple ORG support

117 views
Skip to first unread message

Kent Dickey

unread,
Mar 19, 2021, 2:15:43 AM3/19/21
to
I would like to know if a 6502 assembler for modern Unix systems supports
multiple ORG requests, so that I can force certain routines at fixed
addresses, and insert 0's to fill any space. For example:

org $300
jsr rout320
rts
org $320
rout320
rts

And this will place the JSR and RTS at $300-303, and then 00's and then place
an RTS at $320. I want the final binary result to be:

20 20 03 60,00 00 00 00,00 00 00 00,00 00 00 00,60

and be exactly 33 bytes. If I make an ORG request which cannot work (say,
replace the "org $320" with "org $303", which already contains the previous
RTS) I will accept either a warning or an error, but it cannot be silent.

I'm willing to accept alternative syntax using DS notation:

org $300
jsr rout320
rts
ds $320-*
rout320
rts

where DS means insert $320-current_pc number of 00 bytes. I just need this to
be an error if it overflows, and not 65535 blanks instead.

So, does your favorite 6502 assembler support the above?

Kent
Message has been deleted

I am Rob

unread,
Mar 19, 2021, 3:18:57 AM3/19/21
to
The first way is not possible as there is no way for an assembler to remember what you assembled previously for it to know that if a change to an ORG's address is treading on a pre-existing routine.

The 2nd way "DS $320-*" is the best way, but if you believe the code you want to enter below $320 might over-run $320, then the best way is give yourself some room and start at $340. Once you get the code below $340 efficient and the way you want, then you can close up the code to the nearest useable fixed address.

The only reason I can think of for doing this is, you want to be able to examine the code afterwards and be able to go to that fixed address.
Instead of doing what you want to do at $300 where space is king of limited, consider writing the code higher up in memory where there is lots of room, say $1000, and spread your fixed code out every $100 bytes. Once you get the code the way you like and if space permits, then change the ORG's to fit into $300.

Michael J. Mahon

unread,
Mar 19, 2021, 4:13:22 AM3/19/21
to
Hi, Kent!

Merlin is capable of doing what you want in the second way.

If you want error checking in case the location counter has passed the
desired address, use a macro to issue an “err */$320”, where, for
generality, $320 is replaced by ]1, or the first parameter of the macro.

So:

morg mac ; Org with zero-fill
err */]1 ; Error if past location
ds ]1-*
eom

This assumes that it doesn’t matter what the ds does as long as the error
is flagged. Alternatively, you can use the “if” conditional assembly
construct to bracket the ds.

--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

David Schmidt

unread,
Mar 19, 2021, 9:57:27 AM3/19/21
to
On 3/19/21 2:15 AM, Kent Dickey wrote:
> [...]
> So, does your favorite 6502 assembler support the above?

Multiple orgs are more of a linker construct in the ca65 sense. You aim
bytes at memory using a linker config with defined sections of memory.
That said...

Here's how I complain if I try to get this one thing bigger than 256
bytes, as an example:

;.org $a000
...
;.align 256
;.assert * = $a100, error, "Code got too big to fit in a page!"

Reference:
https://cc65.github.io/doc/ca65.html#s11

Michael Pohoreski

unread,
Mar 19, 2021, 10:59:35 AM3/19/21
to
On Thursday, March 18, 2021 at 11:15:43 PM UTC-7, Kent Dickey wrote:
> I would like to know if a 6502 assembler for modern Unix systems supports
> multiple ORG requests, so that I can force certain routines at fixed
> addresses, and insert 0's to fill any space. For example:
>
> org $300
> jsr rout320
> rts
> org $320
> rout320
> rts

ORG does NOT generate bytes. All it does it is update the assembler what the _next_ output address to use.

> I'm willing to accept alternative syntax using DS notation:

That's not an alternative syntax, that is the primary syntax. ;-)

If you aren't using a linker then you need to tell the assembler to Define Space and fill in padding.

m.

qkumba

unread,
Mar 19, 2021, 12:27:47 PM3/19/21
to
ACME can do something like that, though not using the "ORG" syntax.
Instead, it uses the current address via "*", so
*=$300
...
*=$320
...
etc.
and it will zero-fill in between (and also complain if you have too much code and already occupy the requested address).

Michael Pohoreski

unread,
Mar 19, 2021, 12:34:32 PM3/19/21
to
On Thursday, March 18, 2021 at 11:15:43 PM UTC-7, Kent Dickey wrote:

Another solution is to reserve a page for entry points. You have two options:

1. Use an array of 4C xx xx bytes like this.

ORG $BF00
Foo JMP doFoo
Bar JMP doBar
Qux JMP doQux

2. Do away with wasting one byte per function entry point and just have an array of function pointers
Again here you have to sub-options depending if you are using RTS or JMP.

a) RTS uses words-1
b) JMP use addresses

e.g.
DW Foo-1
DW Bar-1
DW Qux-1

DA Foo
DA Bar
DA Qux

This places the burden on the caller though since you are no longer using a simpler JSR. You need to specify which function to call.

i.e
LDX #1 ; Foo
JSR Trampoline
LDX #2 ; Bar
JSR Trampoline
LDX #3 ; Qux
JSR Trampoline

Trampoline
TXA
ASL
LDA FuncTable+0,X ; low
LDY FuncTable+1,X ; high
STA FuncCall+0 ; ***SELF-MODIFIES
STX FuncCall+1 ; *** SELF-MODIFIES
FuncCall
JMP $C0DE ; *** SELF-MODIFIED

FuncTable
DA Foo
DA Bar
DA Qux


> where DS means insert $320-current_pc number of 00 bytes. I just need this to
> be an error if it overflows, and not 65535 blanks instead.
>
> So, does your favorite 6502 assembler support the above?

I did this on Nox Archaist. We were using Page 3 for font rendering code and didn't want to overflow into the $3F0 vector.
Assembler: sbasm3

Page3End
.DO Page3End>$3EF
.ER F,***Overflow into the IRQ vector!!!
.FI

In case the whitespace gets butchered there should be indentation for .DO and .FI and another indentation for the .ER.

m.

Kent Dickey

unread,
Mar 19, 2021, 3:37:03 PM3/19/21
to
In article <roedncHijdqBwMn9...@giganews.com>,
Michael J. Mahon <mjm...@aol.com> wrote:
>Kent Dickey <ke...@provalid.com> wrote:
>> I would like to know if a 6502 assembler for modern Unix systems supports
>> multiple ORG requests, so that I can force certain routines at fixed
>> addresses, and insert 0's to fill any space. For example:
[ snip ]
OK, I could make the "MORG" work with the following macro:

morg mac
err * > ]1
ds ]1 - *
eom

I need "ds 0" to work, in case the code just happened to line up perfectly.
The above passes my tests so far, so it looks fine.

Also, Merlin32 has a bug where it core dumps on the following:

org $300
jmp $fded
ds $302 - *
jmp $300

The ds being effectively -1 causes the core dump

I like Merlin since I used Merlin-16 on my Apple IIgs, but I don't love the
lack of support for parentheses in expressions.

My intention is to use this to get my version of ROMs to have the ROM
routines to be at the right address. COUT has to be at $FDED, I cannot move
it. And now the source will force it there.

Kent

Kent Dickey

unread,
Mar 19, 2021, 4:08:52 PM3/19/21
to
In article <4dbdfb4b-0e25-4187...@googlegroups.com>,
I tried ACME. It has an unusual directive syntax. It also has no support
for low/high ascii strings (as far as I could tell).


Here's my test file (try1.a):

!cpu 65c02
* = $d000
jmp rout_d234
rts

* = $d108
rout_d108
nop
nop
jmp rout_d234

* = $d234
rout_d234
jmp *
rts
rts
* = $d238
rout_d238
bra *
bra *
nop

Where rout_d238 doesn't fit since * is already at $d239. And this was a
warning. But it forced the PC back a byte, and wiped out the RTS at $d238.
This is not desirable--if it is going to wipe out code, it should be an error.
And the exit code from the acme assembler command is 0, so to catch this, I'd
have to watch the output for the Warning and make it an error.

I like the syntax of expressions, but all the ! commands looks
odd to me. If you use ACME, do you make macros so DFB, DS, etc. work,
or do you stick with the ACME native !byte, etc. pseudo-ops?

Kent

Michael Pohoreski

unread,
Mar 19, 2021, 4:19:08 PM3/19/21
to
On Friday, March 19, 2021 at 12:37:03 PM UTC-7, Kent Dickey wrote:
> Also, Merlin32 has a bug where it core dumps on the following:
>
> org $300
> jmp $fded
> ds $302 - *
> jmp $300
>
> The ds being effectively -1 causes the core dump

Hmm, strange. I get no crash but I don't see the binary or the listing file either. It stops after:
o Build Object Code...

And doesn't get to the Link stage.
o Build Object Code...
+ Link project files...

Guess we should ping Antoinne and/or Olivier in a new thread.

m.

Oliver Schmidt

unread,
Mar 20, 2021, 11:14:25 AM3/20/21
to
Hi,

>I would like to know if a 6502 assembler for modern Unix systems supports
>multiple ORG requests, so that I can force certain routines at fixed
>addresses, and insert 0's to fill any space. For example:
>
> org $300
> jsr rout320
> rts
> org $320
>rout320
> rts
>
>And this will place the JSR and RTS at $300-303, and then 00's and then place
>an RTS at $320. I want the final binary result to be:
>
>20 20 03 60,00 00 00 00,00 00 00 00,00 00 00 00,60
>
>and be exactly 33 bytes. If I make an ORG request which cannot work (say,
>replace the "org $320" with "org $303", which already contains the previous
>RTS) I will accept either a warning or an error, but it cannot be silent.

The seasoned cc65 user would accomplish this with...

demo.s contains:

.segment "s300"
jsr rout320
rts
.segment "s320"
rout320:
rts

demo.cfg contains:

memory {
m: file = %O, start = $300, size = $FFFF;
}
segments {
s300: load m, start = $300;
s320: load m, start = $320;
}

Build it with:
cl65 -t none -C demo.cfg demo.s

It for sure complains if things don't fit.

>I'm willing to accept alternative syntax using DS notation:
>
> org $300
> jsr rout320
> rts
> ds $320-*
>rout320
> rts
>
>where DS means insert $320-current_pc number of 00 bytes. I just need this to
>be an error if it overflows, and not 65535 blanks instead.

The casual ca65 user would accomplish this with...

demo.s contains:

.org $300
jsr rout320
rts
.res $320-*
rout320:
rts

Built it with:
cl65 -t none demo.s

It for sure complains if things don't fit.

>So, does your favorite 6502 assembler support the above?

Yes, see above.

Regards,
Oliver

Antoine Vignau

unread,
Mar 20, 2021, 11:38:05 AM3/20/21
to
Hi There,
This is what I have on my mac:
./Merlin32 -V Library/ sources/test/ds.s
./Merlin32 v1.0 64-bit universal, (c) Brutal Deluxe 2011-2021
+ Assemble project files...
o Loading Sources files...
- ds.s
o Loading Macro files...
o Check for duplicated Macros...
o Decoding lines types...
o Process local/variable Labels...
o Process Asterisk lines...
o Build External table...
o Build Equivalence table...
o Build Variable table...
o Process Equivalence values...
o Replace Macros with Code...
o Replace Lup with code...
o Process MX directives...
o Process Conditional directives...
o Build Label table...
o Check for duplicated Labels...
o Check for unknown Source lines...
o Check for Dum lines...
o Compute Operand Code size...
o Compute Operand Data size...
o Compute Line address...
=> [Error] Error : Evaluation of DS data size ends up as negative value (-1) : '$302-ozunid_1' (line 7, file 'ds.s').
=> Creating Output file 'sources/test/error_output.txt'

Michael J. Mahon

unread,
Mar 21, 2021, 1:13:52 AM3/21/21
to
In (at least) the 8-bit Merlin manuals, in the discussion of ORG, it
specifies that ORG *-n is not a supported construct, and DS -n should be
used to “back up” the location counter.

I’m surprised that Glen changed this on later versions—or did he?
0 new messages