From 3675d7961b09241132206225c8de02dcfa6f28d0 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 11 Dec 2024 18:08:26 +0100 Subject: [PATCH] boolean variables can now also be memory-mapped (including boolean arrays) --- codeCore/src/prog8/code/SymbolTable.kt | 2 +- codeCore/src/prog8/code/ast/AstStatements.kt | 2 +- .../compiler/astprocessing/AstChecker.kt | 4 +-- docs/source/libraries.rst | 2 +- docs/source/portingguide.rst | 2 +- docs/source/programming.rst | 7 +++-- docs/source/targetsystem.rst | 2 +- docs/source/variables.rst | 28 +++++++++++-------- .../src/prog8/intermediate/IRSymbolTable.kt | 2 +- 9 files changed, 29 insertions(+), 22 deletions(-) diff --git a/codeCore/src/prog8/code/SymbolTable.kt b/codeCore/src/prog8/code/SymbolTable.kt index fd860ea5a..7757223a9 100644 --- a/codeCore/src/prog8/code/SymbolTable.kt +++ b/codeCore/src/prog8/code/SymbolTable.kt @@ -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) } diff --git a/codeCore/src/prog8/code/ast/AstStatements.kt b/codeCore/src/prog8/code/ast/AstStatements.kt index bb5b142ac..318f6802f 100644 --- a/codeCore/src/prog8/code/ast/AstStatements.kt +++ b/codeCore/src/prog8/code/ast/AstStatements.kt @@ -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) } } diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index a68c27f39..01f124f99 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -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) diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 091d5dcb6..3087ecd93 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -944,7 +944,7 @@ It's way too much to include here, you have to study the `syslib source code `_ 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()`` diff --git a/docs/source/portingguide.rst b/docs/source/portingguide.rst index f34d4c9fd..8d9e118df 100644 --- a/docs/source/portingguide.rst +++ b/docs/source/portingguide.rst @@ -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. diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 7cf9bb5d7..e68a80a87 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -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. diff --git a/docs/source/targetsystem.rst b/docs/source/targetsystem.rst index b35fca52a..39642f30e 100644 --- a/docs/source/targetsystem.rst +++ b/docs/source/targetsystem.rst @@ -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): diff --git a/docs/source/variables.rst b/docs/source/variables.rst index 21a66f6f5..b19606eb0 100644 --- a/docs/source/variables.rst +++ b/docs/source/variables.rst @@ -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") diff --git a/intermediate/src/prog8/intermediate/IRSymbolTable.kt b/intermediate/src/prog8/intermediate/IRSymbolTable.kt index aab7e6405..d219ebbb2 100644 --- a/intermediate/src/prog8/intermediate/IRSymbolTable.kt +++ b/intermediate/src/prog8/intermediate/IRSymbolTable.kt @@ -166,7 +166,7 @@ class IRStMemVar(name: String, } init { - require(!dt.isBool && !dt.isBoolArray) + require(!dt.isString) } val typeString: String = dt.typeString(length)