Implement BITWIDTH and TZCOUNT functions (#1450)

This commit is contained in:
Sylvie
2024-08-07 10:39:30 -04:00
committed by GitHub
parent 7435630d6a
commit e93190d491
10 changed files with 105 additions and 18 deletions

View File

@@ -9,9 +9,9 @@
.Nm rgbasm
.Nd language documentation
.Sh DESCRIPTION
This is the full description of the language used by
This is the full description of the assembly language used by
.Xr rgbasm 1 .
The description of the instructions supported by the Game Boy CPU is in
For the full description of instructions in the machine language supported by the Game Boy CPU, see
.Xr gbz80 7 .
.Pp
It is advisable to have some familiarity with the Game Boy hardware before reading this document.
@@ -47,6 +47,23 @@ Instructions are assembled into Game Boy opcodes.
Multiple instructions on one line can be separated by double colons
.Ql :: .
.Pp
The available instructions are documented in
.Xr gbz80 7 .
Note that where an instruction requires an 8-bit register
.Ar r8 ,
.Nm
can interpret
.Ic HIGH Ns Pq Ar r16
as the top 8-bit register of the given
.Ar r16 ,
and
.Ic LOW Ns Pq Ar r16
as the bottom one (except for
.Ic LOW Ns Pq Ic AF ,
since
.Ic F
is not a valid register).
.Pp
All reserved keywords (directives, register names, etc.) are case-insensitive;
all identifiers (labels and other symbol names) are case-sensitive.
.Pp
@@ -324,9 +341,33 @@ with a zero constant as either operand will be constant 0, and
.Sq ||
with a non-zero constant as either operand will be constant 1, even if the other operand is non-constant.
.Pp
.Ic \&!
.Sq \&!
returns 1 if the operand was 0, and 0 otherwise.
Even a non-constant operand with any non-zero bits will return 0.
.Ss Integer functions
Besides operators, there are also some functions which have more specialized uses.
.Bl -column "BITWIDTH(n)"
.It Sy Name Ta Sy Operation
.It Fn HIGH n Ta Equivalent to Ql Ar n No & $FF .
.It Fn LOW n Ta Equivalent to Ql Po Ns Ar n No & $FF00 Pc >> 8 .
.EQ
delim $$
.EN
.It Fn BITWIDTH n Ta Returns the number of bits necessary to represent
.Ar n .
Some useful formulas:
.Ic BITWIDTH Ns ( Ar n Ns )\ \-\ 1
equals $\[lf] log sub 2 ( n ) \[rf]$,
.Ic BITWIDTH Ns Pq Ar n Ns \ \-\ 1
equals $\[lc] log sub 2 ( n ) \[rc]$, and
.No 32\ \-\ Ns Ic BITWIDTH Ns Pq Ar n
equals $roman clz ( n )$.
.It Fn TZCOUNT n Ta Returns $roman ctz ( n )$, the count of trailing zero bits at the end of the binary representation of
.Ar n .
.El
.EQ
delim off
.EN
.Ss Fixed-point expressions
Fixed-point numbers are basically normal (32-bit) integers, which count fractions instead of whole numbers.
They offer better precision than integers but limit the range of values.
@@ -345,8 +386,11 @@ Some integer operators like
and
.Sq -
don't care whether the operands are integers or fixed-point.
You can easily truncate a fixed-point number into an integer by shifting it right by 16 bits.
It follows that you can convert an integer to a fixed-point number by shifting it left.
You can easily truncate a fixed-point number into an integer by shifting it right by the number of fractional bits.
It follows that you can convert an integer to a fixed-point number by shifting it left that same amount.
.Pp
Note that the current number of fractional bits can be computed as
.Ic TZCOUNT Ns Pq 1.0 .
.Pp
The following functions are designed to operate with fixed-point numbers:
.EQ
@@ -513,8 +557,8 @@ There is also a character map stack that can be used to save and restore which c
.Sy Note :
Modifications to a character map take effect immediately from that point onward.
.Ss Other functions
There are a few other functions that do various useful things:
.Bl -column "DEF(symbol)"
There are a few other functions that do things beyond numeric or string operations:
.Bl -column "SECTION(symbol)"
.It Sy Name Ta Sy Operation
.It Fn BANK arg Ta Returns a bank number.
If
@@ -552,15 +596,10 @@ If
.Ar arg
is a section type keyword, it returns the starting address of that section type.
The result is not constant, since only RGBLINK can compute its value.
.It Fn DEF symbol Ta Returns TRUE (1) if
.It Fn DEF symbol Ta Returns 1 if
.Ar symbol
has been defined, FALSE (0) otherwise.
has been defined, 0 otherwise.
String constants are not expanded within the parentheses.
.It Fn HIGH arg Ta Returns the top 8 bits of the operand if Ar arg No is a label or constant, or the top 8-bit register if it is a 16-bit register .
.It Fn LOW arg Ta Returns the bottom 8 bits of the operand if Ar arg No is a label or constant, or the bottom 8-bit register if it is a 16-bit register Pq Cm AF No isn't a valid register for this function .
The result may be constant if
.Nm
is able to compute it.
.It Fn ISCONST arg Ta Returns 1 if Ar arg Ap s value is known by RGBASM (e.g. if it can be an argument to
.Ic IF ) ,
or 0 if only RGBLINK can compute its value.