It is currently Mon Feb 18, 2019 9:52 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Wed Jan 16, 2019 9:17 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21101
Location: NE Indiana, USA (NTSC)
I wrote a fairly complex library in ca65.* It spans two files containing assembly language code and three include files: one defining the public API, one defining the data formats and library-internal API, and one configuration file that determines which features shall and shall not be included in the library. The configuration file controls a lot of conditional assembly (.if blocks). It places variables in zero page and BSS, and it places code and data in two segments determined by the config file (which may or may not be CODE and RODATA).

I have received a request for a version of this library compatible with the ASM6 assembler. As I understand it, ASM6 does not have a counterpart to ca65 .res; all variable allocation is handled with equates. In addition, ASM6 does not have a counterpart to ca65 .segment; order of code in the output corresponds to order of code in the input. It does appear to have a counterpart to .scope as rept 1; this could be used to translate a .proc.

Is there a way to bridge this feature gap that is less complex than A. actually writing an assembler that fully parses ca65 code and evaluates its expressions and macros, or B. hand-translating each line from ca65 to ASM6 and finding some way to determine that the code produced by the ca65 version remains identical to the code produced by the ASM6 version even after I fix bugs in or add features to the ca65 version?


* The library is Pently, an audio driver.

EDIT: Yes, .segment. I've been doing too much programming for other platforms lately.


Top
 Profile  
 
PostPosted: Wed Jan 16, 2019 9:26 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7210
Location: Canada
A relatively low-tech workaround might be to just produce a binary blob that must reside at a fixed address? You'd only have to provide the blob and a set of entry point definitions instead. This could work with more or less every assembler, though, not just ASM6, which is maybe a bonus.


Top
 Profile  
 
PostPosted: Wed Jan 16, 2019 9:40 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11166
Location: Rio de Janeiro - Brazil
tepples wrote:
As I understand it, ASM6 does not have a counterpart to ca65 .res; all variable allocation is handled with equates.

.DSB and .DSW are the ASM6 equivalents of .RES. To prevent them from emitting data to the output file, you have to enclose them in .ENUM blocks.

Quote:
In addition, ASM6 does not have a counterpart to ca65 .section; order of code in the output corresponds to order of code in the input.

Do you mean .SEGMENT? Yeah, AFAIK there's no way control the order of things, except for manipulating the order in which they appear in the source code. I personally never found this to be a significant disadvantage... in fact, I kinda prefer this linear philosophy. The only times I ever *needed* to write code out of order in ca65 was to get around the single-pass limitations.

Quote:
It does appear to have a counterpart to .scope as rept 1; this could be used to translate a .proc.

Huh, using .REPT 1 as a makeshift .SCOPE is an interesting idea!

Quote:
Is there a way to bridge this feature gap that is less complex than A. actually writing an assembler that fully parses ca65 code and evaluates its expressions and macros, or B. hand-translating each line from ca65 to ASM6 and finding some way to determine that the code produced by the ca65 version remains identical to the code produced by the ASM6 version even after I fix bugs in or add features to the ca65 version?

I honestly can't think of anything that would make this translation any simpler. I liked rainwarrior's idea of simply including a binary blob, but not only it has to be included in a fixed location, the location of all variables it uses need to be set in stone too, which might be undesirable.


Top
 Profile  
 
PostPosted: Wed Jan 16, 2019 10:04 pm 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 578
Location: Central Illinois, USA
rainwarrior wrote:
A relatively low-tech workaround might be to just produce a binary blob that must reside at a fixed address? You'd only have to provide the blob and a set of entry point definitions instead. This could work with more or less every assembler, though, not just ASM6, which is maybe a bonus.


The problem with the binary blob is that you can't do the conditional compilation based on the configuration file, which I imagine reduces a lot of the flexibility of the library.

_________________
My games: http://www.bitethechili.com


Top
 Profile  
 
PostPosted: Wed Jan 16, 2019 10:18 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11166
Location: Rio de Janeiro - Brazil
I just thought of a way to simulate segments. I admit it's kinda dumb, but here it goes.

First you need a convenient method to reference the segments. You can use .ENUM to create constants that you can easily move around later if you want to change the order of the segments, without having to manually change any numbers. Something like this:
Code:
;create constants for all the segments
.enum 0
   BANK0 .dsb 1
   BANK1 .dsb 1
   ;(...)
   END_OF_SEGMENTS
.ende


Then you can wrap your segmented code in .IF blocks:
Code:
;the following is equivalent to .segment "BANK1"
.if Segment = BANK1

   ;stuff to output to segment "BANK1"

.endif ;except you need to close the block, of course

;the following is equivalent to .segment "BANK0"
.if Segment = BANK0

   ;stuff to output to segment "BANK1"

.endif ;except you need to close the block, of course


Now you need to create a huge list of includes, containing all your source files:
Code:
.include "source0.asm"
.include "source1.asm"
.include "source2.asm"
.include "source3.asm"
;(...)


Finally, in the main file, you just iterate over all segments and include the huge list of includes for each one:
Code:
Segment = 0
.rept END_OF_SEGMENTS
   .include "includes.asm"
   Segment = Segment + 1
.endr


This is obviously not an exact recreation of the segment functionality, seeing as the code for a segment is completely ignored until it's time to output that segment, so you can't do other tasks not related to output (such as modify symbols) in the order the code is written.


Top
 Profile  
 
PostPosted: Wed Jan 16, 2019 10:25 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7210
Location: Canada
gauauu wrote:
The problem with the binary blob is that you can't do the conditional compilation based on the configuration file, which I imagine reduces a lot of the flexibility of the library.

That's kind of a question of how many permutations are reasonable, but at least they could be automated.

Though on the other hand, maybe it'd be reasonable to provide CC65 / build script with it and just have them build the binary blob on their end. The problem should be only be that they're using ASM6 for their existing code, so it may be OK for them to just have CC65 make the blob. The address and everything else would remain fully configurable that way.

Technically, CC65 could even output the ASCII files with the entry points, if you want to avoid adding another tool for that.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group