Re: [cc65] .ORG

Date view Thread view Subject view

From: Ullrich von Bassewitz (uz_at_musoftware.de)
Date: 2000-04-10 22:44:45


				    
On Mon, Apr 10, 2000 at 09:24:05PM +0200, Martin Ancher Holm wrote:
> I've tried to use the .ORG statement like this:
> .RODATA
> .ORG $2000
> .INCBIN "gfx-file"
> to get my graphics at this particular address, but it doesn't work.

Many people have problems with .ORG, and as soon as I start writing a FAQ,
this will be one of the first entries:-)

Most other assemblers for the 6502 handle .ORG different than ca65. The reason
is, that these tools are often working without a linker. Professional
development systems separate the job of the assembler and the linker to gain
more flexibility and to implement features not possible with just one tool.

If you don't have a separate linker, the assembler is responsible for code
translation *and* code placement. With such an assembler, you use the .ORG
directive to place your code at a specific address.

If you have a look at the cc65 library, you will notice that it consists of
several hundred(!) assembler files. Each of these files contains one or more
support subroutines or pieces of data. Without a linker, placement of this
code would be a nightmare, since it depends on your program, which of these
files are actually used, so the runtime address for each one is different for
any program.

To solve this, ca65 creates intermediate files (object files) containing
relocatable code. Instead of absolute code references, complete expression
trees are stored into the object files. Placement of a code section is done by
the linker, and the linker will evaluate the expressions at link time, and
replace it by the real addresses. With a linker, having a lot of object files
with support routines is easy: Since the linker knows which object files will
be part of the final program (because it looks for external symbols in the
library), it can add these modules, calculate the start address for each
module, evaluate the expressions stored inside the object files, and create an
executable containing binary code.

So you should not use ca65 to place your code at a specific address. This is
the job of the linker. Instead create a new segment containing your code, and
use a linker config file to put this segment at the address you want. Using
your example:

       	.segment 	"gfx"
       	.incbin		"gfx-file"
       	.code

(Note that there is no .ORG!)

In the linker config use something like

MEMORY {
    ...
    GFX:       	start = $2000, size = $1000, type = ro, file = %O, fill = yes;
    ...
}

SEGMENTS {
    ...
    gfx:       	load = GFX, type = ro;
    ...
}

You define a memory area at $2000 and tell the linker to place the segment
with the name "gfx" into this area.

In your case, it would probably be a good idea to use a separate assembler
module for each binary include file that contains just the lines

       	.segment	"segmentname"
       	.incbin		"filename"
				  
		  

Now the remaining question is, why is there an .ORG command and what does it
do?

Most people will never use .ORG with ca65, since things will usually work as
expected without it. The linker takes care for all things needed to place some
piece of code at a specific address. If the linker puts your code at address
$1234, it will resolve all jumps and other references, so your code will be
able to run at this address. It is even able to handle different load and run
addresses (this may be needed if your code is placed in a ROM but copied into
RAM before it runs). In fact, using the "load" and "run" attributes of the
linker, it would be possible to get along without using .ORG even in the
situation described below.

The only situation where you need a .ORG directive is, when your code is
placed at a specific address, but it should not be run at this address. A
prominent example would be some code that is loaded into the 1541 CBM floppy.
Having the linker relocate the code to the load address would be wrong, since
the code will be copied at a specific address into the floppy RAM. So what you
need is to tell the assembler to start a section of absolute code. If you do
that, the assembler will still not place the code at a specific address, but
since the final location of the code is already known, there is no need to
make the code relocatable (references to symbols outside the absolute code
range will still create relocation entries resolved by the linker). Code
created with .ORG does not have internal relocation information. It may (must)
be placed at a specific address by the linker, but if this address is not
equal to the absolute address used in the .ORG directive, the code will
usually not run at this address.

Since sections of absolute code are a rare exception with ca65, there is also
a directive to end a section of absolute code: .RELOC switches back to
relocatable mode.

You may use .ORG and .RES to emulate the behaviour of other assemblers (this
may be useful for a short time when porting old code written for other
assemblers), but you loose a lot if you do this, and it's not recommended.

So, while the way ca65 handles things is more complex than the old ".ORG"
stuff, it is also a lot more powerful.

> Now i solve the problem by adding a .RES command:
> .CODE
> 	bla
> 	bla
> .RODATA
> .RES 342
> .INCBIN "music-file"
> .RES 123
> .INCBIN "gfx-file"

If you really want to use .res, you may want to use code like this:

	.rodata
	.org   	$1000
	.incbin	"music-file"
	.res   	$2000-*
	.incbin	"gfx-file"

Since the program counter is known inside a section of absolute code, you can
use an expression to evalute the amount of space to insert.

Regards


	Uz


--
Ullrich von Bassewitz                                  uz_at_musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo_at_musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.


Date view Thread view Subject view

This archive was generated by hypermail 2.1.3 : 2001-12-14 22:05:36 CET