1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/switcher.oph Sat Jun 27 17:51:51 2015 +0200
1.3 @@ -0,0 +1,86 @@
1.4 +; A task switcher for the Acorn Electron.
1.5 +
1.6 +; Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
1.7 +
1.8 +; This program is free software; you can redistribute it and/or modify it under
1.9 +; the terms of the GNU General Public License as published by the Free Software
1.10 +; Foundation; either version 3 of the License, or (at your option) any later
1.11 +; version.
1.12 +
1.13 +; This program is distributed in the hope that it will be useful, but WITHOUT
1.14 +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.15 +; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.16 +; details.
1.17 +
1.18 +; You should have received a copy of the GNU General Public License along with
1.19 +; this program. If not, see <http://www.gnu.org/licenses/>.
1.20 +
1.21 +.include "macros.oph"
1.22 +
1.23 +.org $2000
1.24 +.text
1.25 +
1.26 +main:
1.27 + jsr install_handler
1.28 + rts
1.29 +
1.30 +; install the interrupt handler address in IRQ1V
1.31 +;
1.32 +; affects: A
1.33 +
1.34 +install_handler:
1.35 + sei
1.36 + .invoke mov16 $204, old_handler
1.37 + .invoke store16 handler, $204
1.38 + cli
1.39 + rts
1.40 +
1.41 +; handle interrupts
1.42 +;
1.43 +; affects: (temporary stack usage)
1.44 +
1.45 +handler:
1.46 + pha ; A -> stack
1.47 + txa
1.48 + pha ; X -> stack
1.49 + tya
1.50 + pha ; Y -> stack
1.51 + .invoke push16 $70
1.52 +
1.53 + ; test PC for execution of ROM routines
1.54 + ; these are probably not re-entrant
1.55 +
1.56 + ; obtain the stack location of the stored PC MSB
1.57 + tsx
1.58 + txa
1.59 + clc
1.60 + adc #6 ; offset of MSB (<empty>, Y, X, A, F, LSB, MSB)
1.61 + sta $70
1.62 + lda #$01 ; $01xx
1.63 + sta $71
1.64 +
1.65 + ldx #0
1.66 + lda ($70, x)
1.67 +
1.68 + ; reference the stack location and compute PC MSB & $80
1.69 + and #$80
1.70 + cmp #$80
1.71 +
1.72 + ; exit if PC MSB & $80 != 0
1.73 + beq exit_handler
1.74 +
1.75 + ; increment a counter
1.76 + .invoke add16 1, $7000
1.77 +
1.78 +exit_handler:
1.79 + .invoke pull16 $70
1.80 + pla
1.81 + tay ; stack -> Y
1.82 + pla
1.83 + tax ; stack -> X
1.84 + pla ; stack -> A
1.85 + jmp (old_handler)
1.86 +
1.87 +old_handler: .word 0
1.88 +
1.89 +; vim: tabstop=4 expandtab shiftwidth=4