| |
Kruthers
Registered: Jul 2016 Posts: 21 |
64tass help
Can't figure out how to do something in 64tass. I'm trying to have a main program that knows the labels inside code that is loaded in (ie. unpacked) later. Also, the unpacked code knows the labels in main scope.
Here's a really contrived example of what I mean, but note that it does not work. (Because of conditionals the main has no idea about the effect2 scope...)
I pored over scopes, .logical, .section, etc in the manual but can't crack it.
Any suggestions?
; use compile flags to modify these for emitting different outputs...
.weak
emit_main = true
emit_effect2 = false
.endweak
.if emit_main
* = $1000
; main stays in mem the whole time
main .block
start:
lda #$00
sta effect1.color
jsr effect1.init
jsr effect1.start
jsr unpack_effect2
lda #$0f
sta effect2.color
jsr effect2.init
jsr effect2.start
rts
counter:
.byte ?
.bend
unpack_effect2 .block
; unpack effect2, replacing effect1 in mem
; (pretend there is unpack code here...)
rts
effect2packed:
.binary "effect2-packed.bin"
.bend
* = $1100
; effect1 is compiled and emitted as part of the main prg file
effect1 .block
init:
rts
start:
lda color
sta $d020
inc main.counter
rts
color: .byte ?
.bend
.elsif emit_effect2
* = $1100
; effect2 is NOT emitted as part of the main prg file, but emitted as own
; binary which will be packed and included above
effect2 .block
init:
rts
start:
lda color
sta $d021
inc main.counter
rts
color: .byte ?
.bend
.endif
|
|
| |
oziphantom
Registered: Oct 2014 Posts: 490 |
Not really possible to do what you are thinking, and have it spit out multiple files. Tass has an internal linker not an external linker.
So you either make your effects have a common interface, which solves the main needs to know theirs, and then you can build each part by importing the labels of main.
Or you switch to a larger binary output (like a cart) and you put all the pieces in the larger binary which you then chop up post assemble.
*=$1000
.dsection MAIN
EFFECT1_START
.logical $1100
.dsection EFFECT1
.here
EFFECT2_START
.logical $1100
.dsection EFFECT2
.here
EFFECT_END
then you parse the labels, and split the binary up with MAIN-EFFECT1_START
EFFECT1_START - EFFECT2_START
EFFECT2_START - EFFECT_END
if you are sure all of them will fit into a 64K RAM section, you could space them out ie
*=$1000
.dsection MAIN
*=$4000
.logical $1100
.dsection EFFECT1
.here
*=$8000
.logical $1100
.dsection EFFECT2
.here
and use the non-liner file format which might be easier to parse and split. You can get a 16MB non-linear file however if you are not in 65816 mode, you can't set an address above FFFF which can make it tricky to shove the PC over at times. |
| |
soci
Registered: Sep 2003 Posts: 480 |
I've added "--output-section" in r1590 which can help with this. Normally all sections go into the output file, but this option can be used to tell that only this section and it's children should be output.
Example:
*=$1000
.dsection code1
*=$2000
.dsection code2
.section code1
jsr test
.send
.section code2
test rts
.send
To split this into two files it needs to be compiled twice like this:
64tass --output-section code1 -o code1.prg a.asm
64tass --output-section code2 -o code2.prg a.asm
Those sections which are not part of the output will of course not "overlap" the ones which were included.
The original plan was something similar to how label listing works where you can have several label files output from the same compilation.
But due to some internal limitations it's not possible to do the same for output files yet. The reason is that certain output formats are "destructive" to internal structures therefore the second output file would be wrong.
This delayed output splitting. However requiring multiple compilations is still better than having nothing.
This section output option is untested, in theory it should work. |
| |
oziphantom
Registered: Oct 2014 Posts: 490 |
how would one assemble it such that neither code1 nor code2 was output, and hence one gets "the rest", or is the output section a "list" ? |
| |
Kruthers
Registered: Jul 2016 Posts: 21 |
@oziphantom Yes, I was doing something like that but far uglier (chopping up various outputs), and running out of room in 64k. I would try your idea of making fake "banks" next, but I think soci saved me here...
@soci Thank you! That works perfectly for my contrived example at least. Hopefully this weekend I'll have time to try it out on the real project. Appreciated... |
| |
soci
Registered: Sep 2003 Posts: 480 |
@Kruthers:
I haven't used subtree only output with any real code yet but this sort of use was planned for originally and hope it works now.
The single compilation multiple output problem will be sorted sometime later probably by using some more memory than now. However I'll get in trouble soon if I code too much on side projects while I'm late with the main one.
@oziphantom:
Put the "rest" into a third section which is not a parent of "code1" or "code2" and write it out that way. If for some reason you need placeholders in "rest" for "code1" or "code2" then that can be reserved by ".fill size(code1label)".
I'm not sure if subtree exclusion would be useful in practice. I always just had sibling sections (code, data, etc.) or the same with a bank parent (bank1.code, bank1.data, etc.)
Sections are lists for data only but they are otherwise organized into a tree to allow nesting. The output section parameter selects which branch of the tree will be written out. By default it's the root and then everything gets written out. |
| |
soci
Registered: Sep 2003 Posts: 480 |
With 1.55.2176 it's now possible create multiple output files from a single compilation session.
64tass --output-section code1 -o code1 --output-section code2 -o code2 a.asm
http://tass64.sourceforge.net/#o_output |