From e9163aa3a7adb443496a61b7114cff469a567af0 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 24 Jun 2023 21:04:47 +0200 Subject: [PATCH] added cx16.save_virtual_registers() and cx16.restore_virtual_registers() --- compiler/res/prog8lib/atari/syslib.p8 | 27 +++++++++++++++++ compiler/res/prog8lib/c128/syslib.p8 | 26 +++++++++++++++++ compiler/res/prog8lib/c64/syslib.p8 | 27 +++++++++++++++++ compiler/res/prog8lib/cx16/syslib.p8 | 27 +++++++++++++++++ compiler/res/prog8lib/virtual/syslib.p8 | 39 +++++++++++++++++++++++++ docs/source/libraries.rst | 15 ++++++++++ docs/source/targetsystem.rst | 1 + examples/test.p8 | 32 ++++++++++++-------- 8 files changed, 182 insertions(+), 12 deletions(-) diff --git a/compiler/res/prog8lib/atari/syslib.p8 b/compiler/res/prog8lib/atari/syslib.p8 index 223d83237..b612d99aa 100644 --- a/compiler/res/prog8lib/atari/syslib.p8 +++ b/compiler/res/prog8lib/atari/syslib.p8 @@ -321,4 +321,31 @@ cx16 { &byte r13sH = $1b1b &byte r14sH = $1b1d &byte r15sH = $1b1f + + asmsub save_virtual_registers() clobbers(A,Y) { + %asm {{ + ldy #31 + - lda cx16.r0,y + sta _cx16_vreg_storage,y + dey + bpl - + rts + + _cx16_vreg_storage + .word 0,0,0,0,0,0,0,0 + .word 0,0,0,0,0,0,0,0 + }} + } + + asmsub restore_virtual_registers() clobbers(A,Y) { + %asm {{ + ldy #31 + - lda save_virtual_registers._cx16_vreg_storage,y + sta cx16.r0,y + dey + bpl - + rts + }} + } + } diff --git a/compiler/res/prog8lib/c128/syslib.p8 b/compiler/res/prog8lib/c128/syslib.p8 index 978ce877f..53ee5ac08 100644 --- a/compiler/res/prog8lib/c128/syslib.p8 +++ b/compiler/res/prog8lib/c128/syslib.p8 @@ -874,4 +874,30 @@ cx16 { &byte r13sH = $1b1b &byte r14sH = $1b1d &byte r15sH = $1b1f + + asmsub save_virtual_registers() clobbers(A,Y) { + %asm {{ + ldy #31 + - lda cx16.r0,y + sta _cx16_vreg_storage,y + dey + bpl - + rts + + _cx16_vreg_storage + .word 0,0,0,0,0,0,0,0 + .word 0,0,0,0,0,0,0,0 + }} + } + + asmsub restore_virtual_registers() clobbers(A,Y) { + %asm {{ + ldy #31 + - lda save_virtual_registers._cx16_vreg_storage,y + sta cx16.r0,y + dey + bpl - + rts + }} + } } diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index dc437f119..b56d95756 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -839,4 +839,31 @@ cx16 { &byte r13sH = $cf1b &byte r14sH = $cf1d &byte r15sH = $cf1f + + asmsub save_virtual_registers() clobbers(A,Y) { + %asm {{ + ldy #31 + - lda cx16.r0,y + sta _cx16_vreg_storage,y + dey + bpl - + rts + + _cx16_vreg_storage + .word 0,0,0,0,0,0,0,0 + .word 0,0,0,0,0,0,0,0 + }} + } + + asmsub restore_virtual_registers() clobbers(A,Y) { + %asm {{ + ldy #31 + - lda save_virtual_registers._cx16_vreg_storage,y + sta cx16.r0,y + dey + bpl - + rts + }} + } + } diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index 4fa2c33b9..28234c608 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -629,6 +629,33 @@ asmsub vpoke_mask(ubyte bank @A, uword address @R0, ubyte mask @X, ubyte value @ }} } +asmsub save_virtual_registers() clobbers(A,Y) { + %asm {{ + ldy #31 +- lda cx16.r0,y + sta _cx16_vreg_storage,y + dey + bpl - + rts + +_cx16_vreg_storage + .word 0,0,0,0,0,0,0,0 + .word 0,0,0,0,0,0,0,0 + }} +} + +asmsub restore_virtual_registers() clobbers(A,Y) { + %asm {{ + ldy #31 +- lda save_virtual_registers._cx16_vreg_storage,y + sta cx16.r0,y + dey + bpl - + rts + }} +} + + asmsub save_vera_context() clobbers(A) { ; -- use this at the start of your IRQ handler if it uses Vera registers, to save the state %asm {{ diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index aa58e6476..6c5b7ead4 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -218,4 +218,43 @@ cx16 { &byte r13sH = $ff1d &byte r14sH = $ff1f &byte r15sH = $ff21 + + sub save_virtual_registers() { + uword[32] storage + storage[0] = r0 + storage[1] = r1 + storage[2] = r2 + storage[3] = r3 + storage[4] = r4 + storage[5] = r5 + storage[6] = r6 + storage[7] = r7 + storage[8] = r8 + storage[9] = r9 + storage[10] = r10 + storage[11] = r11 + storage[12] = r12 + storage[13] = r13 + storage[14] = r14 + storage[15] = r15 + } + + sub restore_virtual_registers() { + r0 = cx16.save_virtual_registers.storage[0] + r1 = cx16.save_virtual_registers.storage[1] + r2 = cx16.save_virtual_registers.storage[2] + r3 = cx16.save_virtual_registers.storage[3] + r4 = cx16.save_virtual_registers.storage[4] + r5 = cx16.save_virtual_registers.storage[5] + r6 = cx16.save_virtual_registers.storage[6] + r7 = cx16.save_virtual_registers.storage[7] + r8 = cx16.save_virtual_registers.storage[8] + r9 = cx16.save_virtual_registers.storage[9] + r10 = cx16.save_virtual_registers.storage[10] + r11 = cx16.save_virtual_registers.storage[11] + r12 = cx16.save_virtual_registers.storage[12] + r13 = cx16.save_virtual_registers.storage[13] + r14 = cx16.save_virtual_registers.storage[14] + r15 = cx16.save_virtual_registers.storage[15] + } } diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 4507019d6..43d1b1f02 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -420,6 +420,21 @@ Low-level language support. You should not normally have to bother with this dir The compiler needs it for various built-in system routines. +cx16 +---- +This is available on *all targets*, it is always imported as part of syslib. +On the Commander X16 this module contains a whole bunch of things specific to that machine. +On the other targets, it only contains the definition of the 16 memory mapped virtual registers +(cx16.r0 - cx16.r15) and the following two utility routines: + +``save_virtual_registers()`` + save the values of all 16 virtual registers r0 - r15 in a buffer. Might be useful in an IRQ handler to avoid clobbering them. + +``restore_virtual_registers()`` + restore the values of all 16 virtual registers r0 - r15 from the buffer. Might be useful in an IRQ handler to avoid clobbering them. + + + gfx2 (cx16 only) ----------------- Full-screen multicolor bitmap graphics routines, available on the Cx16 machine only. diff --git a/docs/source/targetsystem.rst b/docs/source/targetsystem.rst index 9ca90cc25..7ed5b2649 100644 --- a/docs/source/targetsystem.rst +++ b/docs/source/targetsystem.rst @@ -166,6 +166,7 @@ will corrupt any Vera operations that were going on in the main program. The rou The Commander X16's 16 'virtual registers' R0-R15 are located in zeropage and *are not preserved* in the IRQ handler! So you should make sure that the handler routine does NOT use these registers, or do some sort of saving/restoring yourself of the ones that you do need in the IRQ handler. + There are two utility routines in cx16 that save and restore *all* 16 registers so it's a bit inefficient but safe. It is also advised to not use floating point calculations inside IRQ handler routines. Beside them being very slow, there are intricate requirements such as having the diff --git a/examples/test.p8 b/examples/test.p8 index c56fc11bb..dcaafa79e 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,22 +1,30 @@ -%import math %import textio %zeropage basicsafe main { sub start() { - ubyte lda = getrandom() - lda++ - cx16.r0 = (math.rnd() % 20) * $0010 - lda = math.rnd() % 5 - lda++ - } + cx16.r0 = $1234 + cx16.r15 = $ea31 - sub getrandom() -> ubyte { - %asm {{ - lda #42 - rts - }} + txt.print_uwhex(cx16.r0, true) + txt.print_uwhex(cx16.r15, true) + txt.nl() + + cx16.save_virtual_registers() + cx16.r0 = $3333 + cx16.r15 = $4444 + + txt.print_uwhex(cx16.r0, true) + txt.print_uwhex(cx16.r15, true) + txt.nl() + cx16.restore_virtual_registers() + + txt.print_uwhex(cx16.r0, true) + txt.print_uwhex(cx16.r15, true) + txt.nl() + repeat { + } } }