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.
This archive was generated by hypermail 2.1.3 : 2001-12-14 22:05:36 CET