Hi Jon,
Thanks for your comments! I guess I should've waited a little longer before upping the version number to 1.0; seems like there are still a few problems here and there...
JonW wrote:
First, using the -di and -do commands to add a file to a disc image. If the file already exists in the di image, it will be added again to the do image, rather than overwritten.
Hmmm... this is curious, as it
should generate an error if you do that. I didn't want to handle overwriting existing files, as I didn't want to effectively reimplement DFS! The idea was that the template disc image specified by -di should contain none of the files which are subsequently written by BeebAsm, and then the output image (-do) should have a different filename. Anyway, I'll look into this and see what's going on.
Quote:
I am converting some existing BBC Basic code to 6502 and have some variable names like status and decode. I can't use these as variable/labels in BeebAsm as it thinks I am trying to STA tus or DEC ode. Can anything be done about this ?
Dave Footitt mentioned this too. I know how I'm going to fix it; I'll try and get it out there as soon as poss.
Quote:
I tend to write in lower case but the assembler doesn't appear to like ,y or ,x. For example sta &100,x complains about a syntax error at the ,x bit.
OK, thanks. Sounds like an easy problem to fix.
Quote:
I also tried to use an expression with brackets in a statement but it didn't like this. For example STA (pc + 1) * 256,X (which I intended to be STA &1A00,X) wouldn't assemble.
Yes - this will look like a malformed STA (ind,X) or STA (ind),Y instruction, and it would be kinda involved to get the parser to recognise this as a valid non-indirect instruction. But there are two possibilities:
Code:
STA 256 * (pc + 1),X
Code:
STA [pc + 1] * 256,X
The square brackets are always available as expression parentheses, to avoid exactly this kind of parsing ambiguity.
Quote:
As for extra features, I would dearly like to be able to declare local variables within a routine and pass parameters to routines. These variables would be stored in the normal page 1 stack and the assembler would automatically generate the necessary code when the variables or parameters were used. I am trying to convert numerous DEFPROC's and DEFFN's to 6502 and trying to handle the parameters and local variables is quite tricky.
Hmmm... do you mean creating a stack frame like modern compilers, and generating code like:
Code:
LDA val1:PHA
LDA val2:PHA
TSX:STX stackframe
....
LDX stackframe:LDA &102,X \ access val1
LDX stackframe:LDA &101,X \ access val2
The problem I see with this is that there are so many ways to code such a thing, and I just think it's too high-level for an assembler. e.g. every local variable access needs to corrupt X, so how do you generate code to preserve X? What if the stack runs out (wraps around)? The problem with hiding the implementation underneath high-level stuff like this is that it distances you from what is actually happening, which I think defeats the point in coding directly in 6502 in the first place.
That said, there
are local symbols, so you could make this a little clearer with:
Code:
.routine
{
localval1 = &102
localval2 = &101
LDA #0:PHA \ initialise localval1 on stack
PHA \ initialise localval2 on stack
TSX:STX stackframe
....
\ fetch localval2 into A
STX temp:LDX stackframe:LDA localval2,X:LDX temp
....
PLA:PLA \ throw away used stack frame
RTS
}
Then I guess a macro could come in useful (though see my comments below!).
Do you need these local variables because of recursion or re-entrancy? If not, I'd suggest just assigning different zp locations for every routine parameter, and the code will be much better. If you do need recursion, why not just push the affected variables to the stack before calling the rouine, and then pull them back and store them afterwards?
Quote:
Perhaps an option to report all assembler errors rather than stop at the first one.
I can have a go!
Quote:
Macros would also be useful.
Hmmm... I never wanted to implement macros for two reasons - firstly, because they just sounded like a pain to code (!), but also because I don't really like to hide the actual generated code behind high-level type constructs, as you can lose valuable optimisations, e.g. a macro like
Code:
(macro add16 a, b)
CLC:LDA a:ADC b:STA a:LDA a+1:ADC b+1:STA a+1
You could use add16 a,b everywhere in the code without giving it any thought, and, yes, it looks tidier and easy-to-read, but every time there are valuable optimisations which are being forgotten... e.g.
* what if you know that carry flag is already clear at the start?
* what if a+1 or b+1 are known to be zero?
I understand that this is just my personal preference though (I personally would not use macros), so if I can find time to add them, I will do.
Quote:
Other than that, I am finding BeebAsm a very useful development tool and I hope some of the ideas above can be taken on board.
Thanks...hopefully I can get some of these fixes in quickly, and will release a new version as soon as possible.