Glass Z80 assembler

Pagina 7/12
1 | 2 | 3 | 4 | 5 | 6 | | 8 | 9 | 10 | 11 | 12

Van DarkSchneider

Paladin (894)

afbeelding van DarkSchneider

26-01-2017, 14:08

For easier, when decided (if the case) to put the REL output, if some of those restrictions are code-related (like symbols lenght to 6 characters and others), simply delegate to the code itself. So it would be the programmer responsability. Just like when using the M80 assembler.

IMO the MSX currently should be approached using compilers and DOS2. Just like a "small PC", that was really the idea (cheap open architecture). Having access to full RAM and with an OS behind, great things could be achieved. Because that I usually encourage for this way.

Van santiontanon

Paladin (868)

afbeelding van santiontanon

01-03-2017, 20:28

Hi, I think there might be a potential bug in the latest version of Glass, I have made the simplest example that does not compile:

    org #4000
    db "AB" ;   ROM signature
    dw Execute  ; start address
    db 0,0,0,0,0,0,0,0,0,0,0,0

CONSTANT1:	equ	0

Execute:
    IF CONSTANT1 = 0
	ld (v1),a
    ENDIF

    ds 8000h - $

    IF CONSTANT1 = 0
v1:              ds virtual 1
    ENDIF

Which does not compile. It gives the error that "v1" is undefined. The problem is that the second "IF CONSTANT1 = 0" does not seem to work as expected. But this should compile, right?

Van santiontanon

Paladin (868)

afbeelding van santiontanon

02-03-2017, 05:45

Oh! and I've also just noticed IF/ELSE/ENDIF do not work if what you have inside of them is an "include" statement.

Sorry for reporting bugs! I know it's annoying to fix them Wink

Van Grauw

Ascended (8682)

afbeelding van Grauw

02-03-2017, 19:18

Hi santiontanon, no problem Smile.

Glass has a bit of a different architecture than most other assemblers, and does (intentionally) not have a preprocessor. This makes it a bit difficult to handle labels defined in IF statements, because IF blocks are processed at a different stage of the assembly process than labels are. I thought I had the common cases covered but it seems it is not good enough. I need to think of a nice solution for this, but it’s non-trivial to address.

In the particular example above you can define the v1 label outside the IF, but I understand that this workaround doesn’t apply to every case.

Anyway I’ll have to look into this.

p.s. When you say “in the latest version of Glass”, do you mean that it used to work in a previous version?

Van santiontanon

Paladin (868)

afbeelding van santiontanon

02-03-2017, 20:04

I see! I think the problem is that I was using it as if it was a #ifdef preprocessor statement in C/C++ Smile
It's not a big deal, since I can just comment things out manually for now, but it'd be a convenient feature to have IF/ENDIFs work also for labels/includes etc. Smile

I did not try in previous versions, but I can try it if you want.

Van syn

Paragon (1937)

afbeelding van syn

04-03-2017, 00:34

I am a bit new at ASM so, what is a preprocessor? Is it something related to C/c++ specific or also general ASM coders?

I don't use Glass, but I see in the tniASM 1.0 manual that I can use if and endif with labels etc, although I have never used this myself.

Van syn

Paragon (1937)

afbeelding van syn

04-03-2017, 00:39

ALSO, I just downloaded Glass to see what it is all about Big smile Will test tomorrow Wink

Van santiontanon

Paladin (868)

afbeelding van santiontanon

04-03-2017, 04:48

Hi Syn! The preprocessor is a process that runs BEFORE the compiler actually translates the assembler to machine code, and prepares the source files so they are ready for the compiler to take them. Typical functions of a preprocessor are things like the "include" commands, where you can include another source file into your main file. What the preprocessor does in this case is to go fetch the file that you included with "include", and copy/paste it directly into your main file. So, long story short, the preprocessor can alter the source file, based on "preprocessor statements" like "include" or "if/else" before giving it to the compiler.

Van Grauw

Ascended (8682)

afbeelding van Grauw

04-03-2017, 22:18

Let me describe the conundrum a bit more in depth;

So the underlying problem is, when to evaluate the IF’s condition. The symbol registration to the scope happens pretty early in the process normally, but at this point I can not evaluate all expressions yet, so I can’t really properly evaluate the IF condition. Because of this, I do not know whether to register the symbol or not yet. Especially when you consider an IF / ELSE which both define a symbol of the same name, given that I can’t register a symbol twice, I don’t know which to register without evaluating the expression.

If you do IF some_flag where some_flag is a constant defined with EQU and defined before the IF, I could in principle evaluate it straight away. But I do not like ordering requirements like that, I don’t think it’s good design, so I try to avoid them.

However if you do e.g. IF $ < 04000H (or are referencing a label defined later) then you need to know the current address, and this information is only available later in the assembly process. This kind of IF I use a lot in combination with errors, to check if code is not in the right area during the compilation.

So currently it is evaluating the IF in the later stage when expressions can be evaluated fully, however this means that if there are labels inside then they also get registered to the scope later. Side note, also not really fond of this late-registration since again it introduces ordering; the label can now be referenced by code coming after it.

I think the proper fix may be to not register the labels in an IF / ELSE block directly, but to register them inside their own scope (like macros do, there’s no problem there), and then register an alias in the outer scope which includes the condition (like a ?: ternary expression). Then the label can be registered early on like everything else, and referenced, but is only evaluated later.

So this would work somewhat like (pseudocode),

conditional: IF test
v1: ret
    ELSE
v1: xor a
    ret
    ENDIF

v1: equ test ? conditional.if.v1 : conditional.else.v1
test: equ 1

Van santiontanon

Paladin (868)

afbeelding van santiontanon

06-03-2017, 05:58

I see. I think I'm so used to the C/C++ preprocessor (in which everything depends on the order in which you define things) that those ordering requirements do not bother me that much Smile

But what you say makes sense. Basically this problem came because I have a project where I have a constant that I set to 0 or 1, depending on whether I want to compile a version that only uses documented Z80 features or one that uses some undocumented instructions. In the undocumented version, there is a variable I don't need, and I put it inside of a IF/ENDIF structure, and that's how the problem came up.

So, for me, any solution that would let me filter variables/includes based on IF/ELSE statements would work. But I admit that implementing it in a way in which there are no order constraints sounds nice!

Pagina 7/12
1 | 2 | 3 | 4 | 5 | 6 | | 8 | 9 | 10 | 11 | 12