mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 19:29:50 +00:00
boolean variables can now also be memory-mapped (including boolean arrays)
This commit is contained in:
parent
f8aaa2d13c
commit
3675d7961b
@ -238,7 +238,7 @@ class StMemVar(name: String,
|
||||
StNode(name, StNodeType.MEMVAR, astNode) {
|
||||
|
||||
init{
|
||||
require(!dt.isBool && !dt.isBoolArray)
|
||||
require(!dt.isString)
|
||||
if(dt.isStringly && !dt.isWord)
|
||||
requireNotNull(length)
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ class PtConstant(name: String, override val type: DataType, val value: Double, p
|
||||
|
||||
class PtMemMapped(name: String, override val type: DataType, val address: UInt, val arraySize: UInt?, position: Position) : PtNamedNode(name, position), IPtVariable {
|
||||
init {
|
||||
require(!type.isBool && !type.isBoolArray)
|
||||
require(!type.isString)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,8 +726,8 @@ internal class AstChecker(private val program: Program,
|
||||
if(decl.datatype.isLong && decl.type!=VarDeclType.CONST)
|
||||
errors.err("cannot use long type for variables; only for constants", decl.position)
|
||||
if(decl.type==VarDeclType.MEMORY) {
|
||||
if (decl.datatype.isBool || decl.datatype.isBoolArray)
|
||||
errors.err("variables mapped in memory should be numeric", decl.position)
|
||||
if (decl.datatype.isString)
|
||||
errors.err("strings cannot be memory-mapped", decl.position)
|
||||
}
|
||||
|
||||
fun err(msg: String) = errors.err(msg, decl.position)
|
||||
|
@ -944,7 +944,7 @@ It's way too much to include here, you have to study the
|
||||
`syslib source code <https://github.com/irmen/prog8/tree/master/compiler/res/prog8lib/cx16/syslib.p8>`_
|
||||
to see what is there.
|
||||
|
||||
On the other targets, it only contains the definition of the 16 memory mapped virtual registers
|
||||
On the other targets, it only contains the definition of the 16 memory-mapped virtual registers
|
||||
(cx16.r0 - cx16.r15) and the following utility routines:
|
||||
|
||||
``save_virtual_registers()``
|
||||
|
@ -40,7 +40,7 @@ RAM, ROM, I/O
|
||||
#. what part(s) of the address space is RAM? What parts of the RAM can be used by user programs?
|
||||
#. what is the usual starting memory address of programs?
|
||||
#. what part(s) of the address space is ROM?
|
||||
#. what part(s) of the address space is memory mapped I/O registers?
|
||||
#. what part(s) of the address space is memory-mapped I/O registers?
|
||||
#. is there a block of "high ram" available (ram that is not the main ram used to load programs in) that could be used for variables?
|
||||
#. is there a banking system? How does it work (how do you select Ram/Rom banks)? How is the default bank configuration set?
|
||||
Note that prog8 itself has no notion of banking, but this knowledge may be required for proper system initialization.
|
||||
|
@ -948,7 +948,8 @@ address of: ``&``
|
||||
Sometimes the compiler silently inserts this operator to make it easier for instance
|
||||
to pass strings or arrays as subroutine call arguments.
|
||||
This operator can also be used as a prefix to a variable's data type keyword to indicate that
|
||||
it is a memory mapped variable (for instance: ``&ubyte screencolor = $d021``)
|
||||
it is a memory-mapped variable (for instance: ``&ubyte screencolor = $d021``). This is explained
|
||||
in the :ref:`variables` chapter.
|
||||
|
||||
ternary:
|
||||
Prog8 doesn't have a ternary operator to choose one of two values (``x? y : z`` in many other languages)
|
||||
@ -1055,8 +1056,8 @@ so pay attention to any jumps and rts instructions in the inlined code!
|
||||
one or more parameters in those 'registers'. You can just list the arguments directly.
|
||||
*This also works on the Commodore 64!* (however they are not as efficient there because they're not in zeropage)
|
||||
In prog8 and assembly code these 'registers' are directly accessible too via
|
||||
``cx16.r0`` .. ``cx16.r15`` (these are memory mapped uword values),
|
||||
``cx16.r0s`` .. ``cx16.r15s`` (these are memory mapped word values),
|
||||
``cx16.r0`` .. ``cx16.r15`` (these are memory-mapped uword values),
|
||||
``cx16.r0s`` .. ``cx16.r15s`` (these are memory-mapped word values),
|
||||
and ``L`` / ``H`` variants are also available to directly access the low and high bytes of these.
|
||||
You can use them directly but their name isn't very descriptive, so it may be useful to define
|
||||
an alias for them when using them regularly.
|
||||
|
@ -6,7 +6,7 @@ Prog8 targets the following hardware:
|
||||
|
||||
- 8 bit MOS 6502/65c02/6510 CPU
|
||||
- 64 Kb addressable memory (RAM or ROM)
|
||||
- optional use of memory mapped I/O registers
|
||||
- optional use of memory-mapped I/O registers
|
||||
- optional use of system ROM routines
|
||||
|
||||
Currently these machines can be selected as a compilation target (via the ``-target`` compiler argument):
|
||||
|
@ -16,7 +16,7 @@ There is *no dynamic memory allocation*. The storage size of all variables
|
||||
is fixed and is determined at compile time.
|
||||
Variable declarations tend to appear at the top of the code block that uses them, but this is not mandatory.
|
||||
They define the name and type of the variable, and its initial value.
|
||||
Prog8 supports a small list of data types, including special 'memory mapped' types
|
||||
Prog8 supports a small list of data types, including special memory-mapped types
|
||||
that don't allocate storage but instead point to a fixed location in the address space.
|
||||
|
||||
|
||||
@ -466,8 +466,8 @@ Range expressions are most often used in for loops, but can be also be used to c
|
||||
byte[] array = 100 to 199 ; initialize array with [100, 101, ..., 198, 199]
|
||||
|
||||
|
||||
Special types: const and memory-mapped
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Constants
|
||||
^^^^^^^^^
|
||||
|
||||
When using ``const``, the value of the 'variable' cannot be changed; it has become a compile-time constant value instead.
|
||||
You'll have to specify the initial value expression. This value is then used
|
||||
@ -478,24 +478,30 @@ Variables on the other hand can't be optimized as much, need memory, and more co
|
||||
Note that a subset of the library routines in the ``math``, ``strings`` and ``floats`` modules are recognised in
|
||||
compile time expressions. For example, the compiler knows what ``math.sin8u(12)`` is and replaces it with the computed result.
|
||||
|
||||
When using ``&`` (the address-of operator but now applied to a datatype), the variable will point to specific location in memory,
|
||||
rather than being newly allocated. The initial value (mandatory) must be a valid
|
||||
memory address. Reading the variable will read the given data type from the
|
||||
address you specified, and setting the variable will directly modify that memory location(s)::
|
||||
|
||||
Memory-mapped
|
||||
^^^^^^^^^^^^^
|
||||
When using ``&`` (the address-of operator but now applied to the datatype in the variable's declaration),
|
||||
the variable will be placed at a designated position in memory rather than being newly allocated somewhere.
|
||||
The initial value in the declaration should be the valid memory address where the variable should be placed.
|
||||
Reading the variable will then read its value from that address, and setting the variable will directly modify those memory location(s)::
|
||||
|
||||
const byte max_age = 2000 - 1974 ; max_age will be the constant value 26
|
||||
&word SCREENCOLORS = $d020 ; a 16-bit word at the address $d020-$d021
|
||||
|
||||
If you need to use the variable's memory address instead of the value placed there, you can still use `&variable` as usual.
|
||||
You can memory map all datatypes except strings.
|
||||
|
||||
|
||||
.. _pointervars:
|
||||
|
||||
Direct access to memory locations ('peek' and 'poke')
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Normally memory locations are accessed by a *memory mapped* name, such as ``cbm.BGCOL0`` that is defined
|
||||
as the memory mapped address $d021 (on the c64 target).
|
||||
Usually specific memory locations are accessed through a memory-mapped variable, such as ``cbm.BGCOL0`` that is defined
|
||||
as the background color register at the memory address $d021 (on the c64 target).
|
||||
|
||||
If you want to access a memory location directly (by using the address itself or via an uword pointer variable),
|
||||
without defining a memory mapped location, you can do so by enclosing the address in ``@(...)``::
|
||||
If you want to access any memory location directly (by using the address itself or via an uword pointer variable),
|
||||
without defining a memory-mapped location, you can do so by enclosing the address in ``@(...)``::
|
||||
|
||||
color = @($d020) ; set the variable 'color' to the current c64 screen border color ("peek(53280)")
|
||||
@($d020) = 0 ; set the c64 screen border to black ("poke 53280,0")
|
||||
|
@ -166,7 +166,7 @@ class IRStMemVar(name: String,
|
||||
}
|
||||
|
||||
init {
|
||||
require(!dt.isBool && !dt.isBoolArray)
|
||||
require(!dt.isString)
|
||||
}
|
||||
|
||||
val typeString: String = dt.typeString(length)
|
||||
|
Loading…
x
Reference in New Issue
Block a user