Skip to content

5. Math expressions, "let", data types

puregorill edited this page Jan 29, 2023 · 16 revisions

The "let" keyword

In C64HLA the "let" command must be used explicitly.
The reason for this "inconvenience" is the property of C64HLA to pass lines unmodified to the assembler if no keyword has been recognised.
"Let" marks a mathematical expression.

Mathematical expressions

Mathematical expressions may also become quite complex in C64HLA as in high level programming languages.
The usual precedence of the operators is taken into account. Expressions in parentheses are allowed.
In order to be able to evaluate the expressions, temporary memory locations/variables must of course be used. These are in the C64's zeropage and are automatically handled by the compiler (see: Memory locations and identifiers).

let [$c000,x] = ( ( some_variable + #40 ) * ( [some_other_variable,x] * #2 ) ) / #3

; Do not forget to enclose complex operands with [...] and to start immediate operands explicitly with #

You are not forced to use complex addressing modes. If you accept a small loss of efficiency, you can also just use the names of the memory locations like variables, as you would in a higher level programming language.

Data types

dbyte - the default byte

If you do not specify an explicit data type in C64HLA expressions and commands, the compiler assumes that it is "dbyte" (read: "default byte"). The data type "dbyte" is never written explicitly.
The type "dbyte" means for mathematical expressions that the compiler relies on the expression never leaving the 8-bit range. This is why a number of "clc" are omitted (of course not the first) and the code becomes faster. The disadvantage is that if the expression leaves the 8-bit range (0-255), the result is wrong, because there is a high probability that no correct carry transfer and rollover takes place.

byte - the explicit byte

To get a correct result after exceeding the 8-bit limit and a rollover, you must explicitly specify "byte" as the target data type.

; If r=1 and x=10 the result will not roll over -> 1 + 240 + 10 = 251
; The use of default "dbyte" is absolutely correct here

  let a = r + #240 + x   

; If r=20 and x=10 the result will roll over -> 20 + 250 = 270 -> carry bit will be set
; The next following addition with x gives a wrong result (off by 1 due to set carry)
; In this case, use "byte" explicitly and the result is correct

  let byte a = r + #250 + x