mirror of
https://github.com/irmen/prog8.git
synced 2025-02-20 03:29:01 +00:00
documented the romsub bank additions
This commit is contained in:
parent
0fc9aa6b2d
commit
cb47e2c149
@ -72,6 +72,7 @@ What does Prog8 provide?
|
|||||||
- inline assembly allows you to have full control when every cycle or byte matters
|
- inline assembly allows you to have full control when every cycle or byte matters
|
||||||
- supports the sixteen 'virtual' 16-bit registers R0 - R15 from the Commander X16 (also available on other targets)
|
- supports the sixteen 'virtual' 16-bit registers R0 - R15 from the Commander X16 (also available on other targets)
|
||||||
- encode strings and characters into petscii or screencodes or even other encodings
|
- encode strings and characters into petscii or screencodes or even other encodings
|
||||||
|
- Automatic ROM/RAM bank switching on certain compiler targets when calling routines in other banks
|
||||||
|
|
||||||
*Rapid edit-compile-run-debug cycle:*
|
*Rapid edit-compile-run-debug cycle:*
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ Features
|
|||||||
- Easy and highly efficient integration with external subroutines and ROM routines on the target systems.
|
- Easy and highly efficient integration with external subroutines and ROM routines on the target systems.
|
||||||
- Strings can contain escaped characters but also many symbols directly if they have a PETSCII equivalent, such as "♠♥♣♦π▚●○╳". Characters like ^, _, \\, {, } and | are also accepted and converted to the closest PETSCII equivalents.
|
- Strings can contain escaped characters but also many symbols directly if they have a PETSCII equivalent, such as "♠♥♣♦π▚●○╳". Characters like ^, _, \\, {, } and | are also accepted and converted to the closest PETSCII equivalents.
|
||||||
- Encode strings and characters into petscii or screencodes or even other encodings, as desired (C64/Cx16)
|
- Encode strings and characters into petscii or screencodes or even other encodings, as desired (C64/Cx16)
|
||||||
|
- Automatic ROM/RAM bank switching on certain compiler targets when calling routines in other banks
|
||||||
- Identifiers can contain Unicode Letters, so ``knäckebröd``, ``приблизительно``, ``見せしめ`` and ``π`` are all valid identifiers.
|
- Identifiers can contain Unicode Letters, so ``knäckebröd``, ``приблизительно``, ``見せしめ`` and ``π`` are all valid identifiers.
|
||||||
- Advanced code optimizations to make the resulting program smaller and faster
|
- Advanced code optimizations to make the resulting program smaller and faster
|
||||||
- Programs can be restarted after exiting (i.e. run them multiple times without having to reload everything), due to automatic variable (re)initializations.
|
- Programs can be restarted after exiting (i.e. run them multiple times without having to reload everything), due to automatic variable (re)initializations.
|
||||||
|
@ -805,7 +805,8 @@ Subroutines are parts of the code that can be repeatedly invoked using a subrout
|
|||||||
Their definition, using the ``sub`` statement, includes the specification of the required parameters and return value.
|
Their definition, using the ``sub`` statement, includes the specification of the required parameters and return value.
|
||||||
Subroutines can be defined in a Block, but also nested inside another subroutine. Everything is scoped accordingly.
|
Subroutines can be defined in a Block, but also nested inside another subroutine. Everything is scoped accordingly.
|
||||||
With ``asmsub`` you can define a low-level subroutine that is implemented directly in assembly and takes parameters
|
With ``asmsub`` you can define a low-level subroutine that is implemented directly in assembly and takes parameters
|
||||||
directly in registers.
|
directly in registers. Finally with ``romsub`` you can define an external subroutine that's implemented outside
|
||||||
|
of the program (for instance, a ROM routine, or a routine in a library loaded elsewhere in RAM).
|
||||||
|
|
||||||
Trivial ``asmsub`` routines can be tagged as ``inline`` to tell the compiler to copy their code
|
Trivial ``asmsub`` routines can be tagged as ``inline`` to tell the compiler to copy their code
|
||||||
in-place to the locations where the subroutine is called, rather than inserting an actual call and return to the
|
in-place to the locations where the subroutine is called, rather than inserting an actual call and return to the
|
||||||
|
@ -781,10 +781,10 @@ The parameters is a (possibly empty) comma separated list of "<datatype> <parame
|
|||||||
The return type has to be specified if the subroutine returns a value.
|
The return type has to be specified if the subroutine returns a value.
|
||||||
|
|
||||||
|
|
||||||
Assembly / ROM subroutines
|
External subroutines
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
External subroutines implemented in ROM are usually defined by compiler library files, with the following syntax::
|
External subroutines are usually defined by compiler library files, with the following syntax::
|
||||||
|
|
||||||
romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) clobbers()
|
romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) clobbers()
|
||||||
-> bool @Pc, ubyte @ A, ubyte @ X, ubyte @ Y
|
-> bool @Pc, ubyte @ A, ubyte @ X, ubyte @ Y
|
||||||
@ -793,9 +793,14 @@ This defines the ``LOAD`` subroutine at memory address $FFD5, taking arguments i
|
|||||||
and returning stuff in several registers as well. The ``clobbers`` clause is used to signify to the compiler
|
and returning stuff in several registers as well. The ``clobbers`` clause is used to signify to the compiler
|
||||||
what CPU registers are clobbered by the call instead of being unchanged or returning a meaningful result value.
|
what CPU registers are clobbered by the call instead of being unchanged or returning a meaningful result value.
|
||||||
|
|
||||||
|
**Banks:** it is possible to declare a non-standard ROM or RAM bank that the routine is living in, with ``@rombank`` or ``@rambank`` like this:
|
||||||
|
``romsub @rombank 10 $C09F = audio_init()`` to define a routine at $C09F in ROM bank 10.
|
||||||
|
See :ref:`banking` for more information.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Unlike what it's name may suggest, ``romsub`` can also define an external subroutine elsewhere in normal RAM.
|
``romsub`` is most often used to define ROM subroutines. But contrary to what the name may suggest,
|
||||||
It's just that you explicitly define the memory address where it is located and it doesn't matter if that is in ROM or in RAM.
|
it can also define an external subroutine elsewhere in normal RAM. It simply states the address
|
||||||
|
and signature of the subroutine; it doesn't care if the routine is in ROM or RAM address space.
|
||||||
|
|
||||||
User-written subroutines in the program source code itself, implemented purely in assembly and which have an assembly calling convention (i.e.
|
User-written subroutines in the program source code itself, implemented purely in assembly and which have an assembly calling convention (i.e.
|
||||||
the parameters are strictly passed via cpu registers), are defined with ``asmsub`` like this::
|
the parameters are strictly passed via cpu registers), are defined with ``asmsub`` like this::
|
||||||
|
@ -25,6 +25,44 @@ It is possible to relocate the BSS section using a compiler option
|
|||||||
so that more system ram is available for the program code itself.
|
so that more system ram is available for the program code itself.
|
||||||
|
|
||||||
|
|
||||||
|
.. _banking:
|
||||||
|
|
||||||
|
ROM/RAM bank selection
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
On certain systems prog8 provides support for managing the ROM or RAM banks that are active.
|
||||||
|
For example, on the Commander X16, you can use ``cx16.getrombank()`` to get the active ROM bank,
|
||||||
|
and ``cx16.rombank(10)`` to make rom bank 10 active. Likewise, ``cx16.getrambank()`` to get the active RAM bank,
|
||||||
|
and ``cx16.rambank(10)`` to make ram bank 10 active. This is explicit manual banking control.
|
||||||
|
|
||||||
|
However, Prog8 also provides something more sophisticated than this, when dealing with banked subroutines:
|
||||||
|
|
||||||
|
External subroutines defined with ``romsub`` can have a non-standard ROM or RAM bank specified as well.
|
||||||
|
The compiler will then transparently change a call to this routine so that the correct bank is activated
|
||||||
|
automatically before the normal jump to the subroutine (and switched back on return). The programmer doesn't
|
||||||
|
have to bother anymore with setting/resetting the banks manually, or having the program crash because
|
||||||
|
the routine is called in the wrong bank! You define such a routine by adding ``@rombank <bank>`` or ``@rambank <bank>``
|
||||||
|
to the romsub subroutine definition. This specifies the bank number where the subroutine is located in::
|
||||||
|
|
||||||
|
romsub @rombank 10 $C09F = audio_init()
|
||||||
|
|
||||||
|
When you then call this routine in your program as usual, the compiler will no longer generate a simple JSR instruction to the
|
||||||
|
routine. Instead it will generate a piece of code that automatically switches the ROM or RAM bank to the
|
||||||
|
correct value, does the call, and switches the bank back. The exact code will be different for different
|
||||||
|
compilation targets, and not all targets even have banking or support this. As an example,
|
||||||
|
on the Commander X16, prog8 will use the JSRFAR kernal routine for this. On the Commodore 128, a similar call exists.
|
||||||
|
Other compilation targets don't have banking or prog8 doesn't yet support automatic bank selection on them.
|
||||||
|
|
||||||
|
Notice that the symbol for this routine in the assembly source code will still be defined as usual.
|
||||||
|
The bank number is not translated into assembly (only as a comment)::
|
||||||
|
|
||||||
|
p8s_audio_init = $c09f ; @rombank 10
|
||||||
|
|
||||||
|
.. caution::
|
||||||
|
Calls with automatic bank switching like this are not safe to use from IRQ handlers. Don't use them there.
|
||||||
|
Instead change banks in a controlled manual way (or not at all).
|
||||||
|
|
||||||
|
|
||||||
.. _symbol-prefixing:
|
.. _symbol-prefixing:
|
||||||
|
|
||||||
Symbol prefixing in generated Assembly code
|
Symbol prefixing in generated Assembly code
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
add docs for @rombank @rambank on romsubs. Add promo in docs that prog8 does automatic bank switching when calling such a romsub (on cx16 and c128)
|
consolidate @rombank and @rambank into just @bank
|
||||||
|
|
||||||
rename 'romsub' to 'extsub' ?
|
add example for cx16 that compiles and loads libraries in different ram banks and calls romsub from rom and ram banks automatically
|
||||||
|
|
||||||
for releasenotes: gfx2.width and gfx2.height got renamed as gfx_lores.WIDTH/HEIGHT or gfx_hires4.WIDTH/HEIGTH constants. Screen mode routines also renamed.
|
for releasenotes: gfx2.width and gfx2.height got renamed as gfx_lores.WIDTH/HEIGHT or gfx_hires4.WIDTH/HEIGTH constants. Screen mode routines also renamed.
|
||||||
|
|
||||||
regenerate symbol dump files
|
add support for banked romsubs on the C64 as well (banks basic/kernal rom in/out)
|
||||||
|
|
||||||
|
rename 'romsub' to 'extsub' ? keep romsub as alias?
|
||||||
|
|
||||||
|
regenerate symbol dump files
|
||||||
|
|
||||||
Improve register load order in subroutine call args assignments:
|
Improve register load order in subroutine call args assignments:
|
||||||
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
|
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
|
||||||
|
@ -3,27 +3,11 @@
|
|||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
romsub @rombank 10 $C09F = audio_init()
|
||||||
|
romsub @rambank 22 $A000 = hiram_routine()
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
block1.sub1()
|
audio_init()
|
||||||
block1.sub2()
|
hiram_routine()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block1 {
|
|
||||||
%option merge
|
|
||||||
|
|
||||||
sub sub1() {
|
|
||||||
txt.print("sub1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
block1 {
|
|
||||||
%option merge
|
|
||||||
|
|
||||||
sub sub2() {
|
|
||||||
txt.print("sub2")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user