mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
docs about irq handlers
This commit is contained in:
parent
77dc35dc6a
commit
06f0984fa1
@ -544,7 +544,9 @@ will issue a warning then telling you the result values of a subroutine call are
|
||||
subroutines are *non-reentrant*. This means you cannot create recursive calls.
|
||||
If you do need a recursive algorithm, you'll have to hand code it in embedded assembly for now,
|
||||
or rewrite it into an iterative algorithm.
|
||||
Also, subroutines used in the main program should not be used from an IRQ handler.
|
||||
Also, subroutines used in the main program should not be used from an IRQ handler. This is because
|
||||
the subroutine may be interrupted, and will then call itself from the IRQ handler. Results are
|
||||
then undefined because the variables will get overwritten.
|
||||
|
||||
|
||||
.. _builtinfunctions:
|
||||
@ -738,3 +740,16 @@ rrestore()
|
||||
|
||||
read_flags()
|
||||
Returns the current value of the CPU status register.
|
||||
|
||||
|
||||
|
||||
Library routines
|
||||
----------------
|
||||
|
||||
There are many routines available in the compiler libraries.
|
||||
Some are used internally by the compiler as well.
|
||||
There's too many to list here, just have a look through the source code
|
||||
of the library modules to see what's there.
|
||||
(They can be found in the compiler/res directory)
|
||||
The example programs also use a small set of the library routines, you can study
|
||||
their source code to see how they might be used.
|
||||
|
@ -145,3 +145,35 @@ Arguments and result values are passed via global variables stored in memory
|
||||
*These are not allocated on a stack* so it is not possible to create recursive calls!
|
||||
The result value(s) of a subroutine are returned on the evaluation stack,
|
||||
to make it possible to use subroutines in expressions.
|
||||
|
||||
|
||||
IRQ Handling
|
||||
============
|
||||
|
||||
Normally, the system's default IRQ handling is not interfered with.
|
||||
You can however install your own IRQ handler.
|
||||
This is possible ofcourse by doing it all using customized inline assembly,
|
||||
but there are a few library routines available to make setting up C-64 IRQs and raster IRQs a lot easier (no assembly code required).
|
||||
|
||||
These routines are::
|
||||
|
||||
c64utils.set_irqvec()
|
||||
c64utils.set_irqvec_excl()
|
||||
|
||||
c64utils.set_rasterirq( <raster line> )
|
||||
c64utils.set_rasterirq_excl( <raster line> )
|
||||
|
||||
c64utils.restore_irqvec() ; set it back to the systems default irq handler
|
||||
|
||||
If you activate an IRQ handler with one of these, it expects the handler to be defined
|
||||
as a subroutine ``irq`` in the module ``irq`` so like this::
|
||||
|
||||
~ irq {
|
||||
sub irq() {
|
||||
; ... irq handling here ...
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.. todo::
|
||||
@todo the irq handler should use its own eval-stack to avoid stack interference issues
|
||||
|
@ -1,3 +1,10 @@
|
||||
|
||||
; TehTriz - a Tetris clone.
|
||||
;
|
||||
; @todo: hold block.
|
||||
; @todo: show next 2 blocks instead of just 1.
|
||||
|
||||
|
||||
~ main {
|
||||
|
||||
const ubyte boardOffsetX = 14
|
||||
@ -52,7 +59,9 @@ waitkey:
|
||||
if_z goto waitkey
|
||||
|
||||
if key>='1' and key<='7' {
|
||||
; select block type
|
||||
; select block type, reset to start pos
|
||||
xpos = startXpos
|
||||
ypos = startYpos
|
||||
drawBlock(xpos, ypos, 32)
|
||||
blocklogic.newCurrentBlock(key-'1')
|
||||
drawBlock(xpos, ypos, 160)
|
||||
@ -202,52 +211,55 @@ waitkey:
|
||||
ubyte[16] currentBlock
|
||||
ubyte[16] rotated
|
||||
|
||||
; block colors I, J, L, O, S, T, Z: cyan, blue, orange, yellow, green, purple, red
|
||||
ubyte[7] blockColors = [3, 6, 8, 7, 5, 4, 2]
|
||||
ubyte[4] blockI = [4, 5, 6, 7] ; note: special rotation (only 2 states)
|
||||
ubyte[4] blockJ = [0, 4, 5, 6]
|
||||
ubyte[4] blockL = [2, 4, 5, 6]
|
||||
ubyte[4] blockO = [1, 2, 5, 6] ; note: no rotation (square)
|
||||
ubyte[4] blockS = [1, 2, 4, 5]
|
||||
ubyte[4] blockT = [1, 4, 5, 6]
|
||||
ubyte[4] blockZ = [0, 1, 5, 6]
|
||||
; the 7 tetrominos
|
||||
ubyte[16] blockI = [0,0,0,0, ; cyan ; note: special rotation (only 2 states)
|
||||
3,3,3,3,
|
||||
0,0,0,0,
|
||||
0,0,0,0]
|
||||
ubyte[16] blockJ = [6,0,0,0, ; blue
|
||||
6,6,6,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0]
|
||||
ubyte[16] blockL = [0,0,8,0, ; orange
|
||||
8,8,8,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0]
|
||||
ubyte[16] blockO = [0,7,7,0, ; yellow ; note: no rotation (square)
|
||||
0,7,7,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0]
|
||||
ubyte[16] blockS = [0,5,5,0, ; green
|
||||
5,5,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0]
|
||||
ubyte[16] blockT = [0,4,0,0, ; purple
|
||||
4,4,4,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0]
|
||||
ubyte[16] blockZ = [2,2,0,0, ; red
|
||||
0,2,2,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0]
|
||||
|
||||
; @todo would be nice to have a pointer type, like so:
|
||||
; uword[7] blocks = [&blockI, &blockJ, &blockL, &blockO, &blockS, &blockT, &blockZ]
|
||||
|
||||
sub newCurrentBlock(ubyte block) {
|
||||
memset(currentBlock, len(currentBlock), 0)
|
||||
currentBlockNum = block
|
||||
|
||||
; @todo would be nice to have an explicit pointer type to reference the array, and code the loop only once...
|
||||
ubyte blockCol = blockColors[block]
|
||||
ubyte i
|
||||
if block==0 { ; I
|
||||
for i in blockI
|
||||
currentBlock[i] = blockCol
|
||||
}
|
||||
else if block==1 { ; J
|
||||
for i in blockJ
|
||||
currentBlock[i] = blockCol
|
||||
}
|
||||
else if block==2 { ; L
|
||||
for i in blockL
|
||||
currentBlock[i] = blockCol
|
||||
}
|
||||
else if block==3 { ; O
|
||||
for i in blockO
|
||||
currentBlock[i] = blockCol
|
||||
}
|
||||
else if block==4 { ; S
|
||||
for i in blockS
|
||||
currentBlock[i] = blockCol
|
||||
}
|
||||
else if block==5 { ; T
|
||||
for i in blockT
|
||||
currentBlock[i] = blockCol
|
||||
}
|
||||
else if block==6 { ; Z
|
||||
for i in blockZ
|
||||
currentBlock[i] = blockCol
|
||||
}
|
||||
if block==0
|
||||
memcopy(blockI, currentBlock, len(currentBlock))
|
||||
else if block==1
|
||||
memcopy(blockJ, currentBlock, len(currentBlock))
|
||||
else if block==2
|
||||
memcopy(blockL, currentBlock, len(currentBlock))
|
||||
else if block==3
|
||||
memcopy(blockO, currentBlock, len(currentBlock))
|
||||
else if block==4
|
||||
memcopy(blockS, currentBlock, len(currentBlock))
|
||||
else if block==5
|
||||
memcopy(blockT, currentBlock, len(currentBlock))
|
||||
else if block==6
|
||||
memcopy(blockZ, currentBlock, len(currentBlock))
|
||||
}
|
||||
|
||||
sub rotateCW() {
|
||||
|
@ -5,8 +5,6 @@
|
||||
|
||||
; @todo see problem in looplabelproblem.p8
|
||||
|
||||
; @todo gradle fatJar should include the antlr runtime jar
|
||||
|
||||
sub start() {
|
||||
|
||||
uword w = 12345
|
||||
|
Loading…
x
Reference in New Issue
Block a user