Moved IRQ hooking / unhooking from startup code to constructor / destructor to avoid linking in the hooking / unhooking code (and callirq) for the majority of cc65 prorams not linking in interruptors.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5985 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
ol.sc
2013-02-12 22:39:38 +00:00
parent 1607b05104
commit 7c9171ee87
36 changed files with 886 additions and 732 deletions

View File

@@ -104,6 +104,7 @@ S_OBJS= _scrsize.o \
home.o \ home.o \
initcwd.o \ initcwd.o \
iobuf.o \ iobuf.o \
irq.o \
isdevice.o \ isdevice.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \

View File

@@ -8,17 +8,14 @@
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import zerobss .import zerobss
.import initlib, donelib .import initlib, donelib
.import callmain, callirq .import callmain
.import __LC_START__, __LC_LAST__ ; Linker generated .import __LC_START__, __LC_LAST__ ; Linker generated
.import __INIT_RUN__, __INIT_SIZE__ ; Linker generated .import __INIT_RUN__, __INIT_SIZE__ ; Linker generated
.import __ZPSAVE_RUN__ ; Linker generated .import __ZPSAVE_RUN__ ; Linker generated
.import __INTERRUPTOR_COUNT__ ; Linker generated
.include "zeropage.inc" .include "zeropage.inc"
.include "apple2.inc" .include "apple2.inc"
; ------------------------------------------------------------------------
.segment "STARTUP" .segment "STARTUP"
; ProDOS TechRefMan, chapter 5.2.1: ; ProDOS TechRefMan, chapter 5.2.1:
@@ -89,16 +86,6 @@ _exit: ldx #<exit
; Call module destructors ; Call module destructors
jsr donelib jsr donelib
; Check for valid interrupt vector table entry number
lda int_num
beq exit
; Deallocate interrupt vector table entry
dec i_param ; Adjust parameter count
jsr $BF00 ; MLI call entry point
.byte $41 ; Dealloc interrupt
.addr i_param
; Restore the original RESET vector ; Restore the original RESET vector
exit: ldx #$02 exit: ldx #$02
: lda rvsave,x : lda rvsave,x
@@ -122,8 +109,6 @@ exit: ldx #$02
; We're done ; We're done
jmp (done) jmp (done)
; ------------------------------------------------------------------------
.segment "INIT" .segment "INIT"
; Save the zero page locations we need ; Save the zero page locations we need
@@ -179,26 +164,12 @@ basic: lda HIMEM
: sta sp : sta sp
stx sp+1 stx sp+1
; Check for interruptors
lda #<__INTERRUPTOR_COUNT__
beq :+
; Check for ProDOS
cpy #$4C ; Is MLI present? (JMP opcode)
bne prterr
; Allocate interrupt vector table entry
jsr $BF00 ; MLI call entry point
.byte $40 ; Alloc interrupt
.addr i_param
bcs prterr
; Enable interrupts as old ProDOS versions (i.e. 1.1.1) ; Enable interrupts as old ProDOS versions (i.e. 1.1.1)
; jump to SYS and BIN programs with interrupts disabled ; jump to SYS and BIN programs with interrupts disabled
cli cli
; Call module constructors ; Call module constructors
: jsr initlib jsr initlib
; Switch in LC bank 2 for R/O ; Switch in LC bank 2 for R/O
bit $C080 bit $C080
@@ -206,53 +177,7 @@ basic: lda HIMEM
; Push arguments and call main() ; Push arguments and call main()
jmp callmain jmp callmain
; Print error message and return .code
prterr: ldx #msglen-1
: lda errmsg,x
jsr $FDED ; COUT
dex
bpl :-
rts
errmsg: .ifdef __APPLE2ENH__
.byte $8D, 't'|$80, 'p'|$80, 'u'|$80, 'r'|$80, 'r'|$80
.byte 'e'|$80, 't'|$80, 'n'|$80, 'i'|$80, ' '|$80, 'c'|$80
.byte 'o'|$80, 'l'|$80, 'l'|$80, 'a'|$80, ' '|$80, 'o'|$80
.byte 't'|$80, ' '|$80, 'd'|$80, 'e'|$80, 'l'|$80, 'i'|$80
.byte 'a'|$80, 'F'|$80, $8D
.else
.byte $8D, 'T'|$80, 'P'|$80, 'U'|$80, 'R'|$80, 'R'|$80
.byte 'E'|$80, 'T'|$80, 'N'|$80, 'I'|$80, ' '|$80, 'C'|$80
.byte 'O'|$80, 'L'|$80, 'L'|$80, 'A'|$80, ' '|$80, 'O'|$80
.byte 'T'|$80, ' '|$80, 'D'|$80, 'E'|$80, 'L'|$80, 'I'|$80
.byte 'A'|$80, 'F'|$80, $8D
.endif
msglen = * - errmsg
; ------------------------------------------------------------------------
.segment "LOWCODE"
; ProDOS TechRefMan, chapter 6.2:
; "Each installed routine must begin with a CLD instruction."
intptr: cld
; Call interruptors and check for success
jsr callirq
bcc :+
; ProDOS TechRefMan, chapter 6.2:
; "When the routine that can process the interrupt is called, it
; should ... return (via an RTS) with the carry flag clear."
clc
rts
; ProDOS TechRefMan, chapter 6.2:
; "When a routine that cannot process the interrupt is called,
; it should return (via an RTS) with the cary flag set ..."
: sec
rts
; Setup RESET vector ; Setup RESET vector
reset: stx SOFTEV reset: stx SOFTEV
@@ -266,8 +191,6 @@ quit: jsr $BF00 ; MLI call entry point
.byte $65 ; Quit .byte $65 ; Quit
.word q_param .word q_param
; ------------------------------------------------------------------------
.rodata .rodata
; MLI parameter list for quit ; MLI parameter list for quit
@@ -277,26 +200,15 @@ q_param:.byte $04 ; param_count
.byte $00 ; reserved .byte $00 ; reserved
.word $0000 ; reserved .word $0000 ; reserved
; ------------------------------------------------------------------------
.data .data
; MLI parameter list for (de)alloc interrupt
i_param:.byte $02 ; param_count
int_num:.byte $00 ; int_num
.addr intptr ; int_code
; Location to jump to when we're done ; Location to jump to when we're done
done: .addr DOSWARM done: .addr DOSWARM
; ------------------------------------------------------------------------
.segment "ZPSAVE" .segment "ZPSAVE"
zpsave: .res zpspace zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss .bss
rvsave: .res 3 rvsave: .res 3

94
libsrc/apple2/irq.s Normal file
View File

@@ -0,0 +1,94 @@
;
; Oliver Schmidt, 2012-11-17
;
; IRQ handling (Apple2 version)
;
.export initirq, doneirq
.import callirq, __dos_type, _exit
.include "zeropage.inc"
.include "apple2.inc"
.segment "INIT"
initirq:
; Check for ProDOS
lda __dos_type
beq prterr
; Allocate interrupt vector table entry
jsr $BF00 ; MLI call entry point
.byte $40 ; Alloc interrupt
.addr i_param
bcs prterr
rts
; Print error message and exit
prterr: ldx #msglen-1
: lda errmsg,x
jsr $FDED ; COUT
dex
bpl :-
jmp _exit
errmsg: .ifdef __APPLE2ENH__
.byte $8D, 't'|$80, 'p'|$80, 'u'|$80, 'r'|$80, 'r'|$80
.byte 'e'|$80, 't'|$80, 'n'|$80, 'i'|$80, ' '|$80, 'c'|$80
.byte 'o'|$80, 'l'|$80, 'l'|$80, 'a'|$80, ' '|$80, 'o'|$80
.byte 't'|$80, ' '|$80, 'd'|$80, 'e'|$80, 'l'|$80, 'i'|$80
.byte 'a'|$80, 'F'|$80, $8D
.else
.byte $8D, 'T'|$80, 'P'|$80, 'U'|$80, 'R'|$80, 'R'|$80
.byte 'E'|$80, 'T'|$80, 'N'|$80, 'I'|$80, ' '|$80, 'C'|$80
.byte 'O'|$80, 'L'|$80, 'L'|$80, 'A'|$80, ' '|$80, 'O'|$80
.byte 'T'|$80, ' '|$80, 'D'|$80, 'E'|$80, 'L'|$80, 'I'|$80
.byte 'A'|$80, 'F'|$80, $8D
.endif
msglen = * - errmsg
.code
doneirq:
; Check for valid interrupt vector table entry number which
; IS necessary as this gets called even if initirq failed.
lda int_num
beq :+
; Deallocate interrupt vector table entry
dec i_param ; Adjust parameter count
jsr $BF00 ; MLI call entry point
.byte $41 ; Dealloc interrupt
.addr i_param
: rts
.segment "LOWCODE"
intptr:
; ProDOS TechRefMan, chapter 6.2:
; "Each installed routine must begin with a CLD instruction."
cld
; Call interruptors and check for success
jsr callirq
bcc :+
; ProDOS TechRefMan, chapter 6.2:
; "When the routine that can process the interrupt is called, it
; should ... return (via an RTS) with the carry flag clear."
clc
rts
; ProDOS TechRefMan, chapter 6.2:
; "When a routine that cannot process the interrupt is called,
; it should return (via an RTS) with the cary flag set ..."
: sec
rts
.data
; MLI parameter list for (de)alloc interrupt
i_param:.byte $02 ; param_count
int_num:.byte $00 ; int_num
.addr intptr ; int_code

View File

@@ -4,7 +4,7 @@
; void rebootafterexit (void); ; void rebootafterexit (void);
; ;
.constructor initreboot .constructor initreboot, 11
.export _rebootafterexit .export _rebootafterexit
.import done, return .import done, return

View File

@@ -107,6 +107,7 @@ S_OBJS= _scrsize.o \
home.o \ home.o \
initcwd.o \ initcwd.o \
iobuf.o \ iobuf.o \
irq.o \
isdevice.o \ isdevice.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \

View File

@@ -103,6 +103,7 @@ OBJS = _scrsize.o \
graphics.o \ graphics.o \
initcwd.o \ initcwd.o \
inviocb.o \ inviocb.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

View File

@@ -12,8 +12,7 @@
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib .import initlib, donelib
.import callmain, zerobss, callirq .import callmain, zerobss
.import __INTERRUPTOR_COUNT__
.import __STARTUP_LOAD__, __ZPSAVE_LOAD__ .import __STARTUP_LOAD__, __ZPSAVE_LOAD__
.import __RESERVED_MEMORY__ .import __RESERVED_MEMORY__
@@ -23,7 +22,8 @@
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; EXE header ; EXE header
.segment "EXEHDR" .segment "EXEHDR"
.word $FFFF .word $FFFF
.word __STARTUP_LOAD__ .word __STARTUP_LOAD__
.word __ZPSAVE_LOAD__ - 1 .word __ZPSAVE_LOAD__ - 1
@@ -31,7 +31,7 @@
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Actual code ; Actual code
.segment "STARTUP" .segment "STARTUP"
rts ; fix for SpartaDOS / OS/A+ rts ; fix for SpartaDOS / OS/A+
; they first call the entry point from AUTOSTRT and ; they first call the entry point from AUTOSTRT and
@@ -74,22 +74,9 @@ L1: lda sp,x
sta APPMHI+1 sta APPMHI+1
sta sp+1 ; setup runtime stack part 2 sta sp+1 ; setup runtime stack part 2
; If we have IRQ functions, chain our stub into the IRQ vector
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda VVBLKI
ldx VVBLKI+1
sta IRQInd+1
stx IRQInd+2
lda #6
ldy #<IRQStub
ldx #>IRQStub
jsr SETVBV
; Call module constructors ; Call module constructors
NoIRQ1: jsr initlib jsr initlib
; Set left margin to 0 ; Set left margin to 0
@@ -117,19 +104,9 @@ NoIRQ1: jsr initlib
_exit: jsr donelib ; Run module destructors _exit: jsr donelib ; Run module destructors
; Reset the IRQ vector if we chained it.
pha ; Save the return code on stack
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ2
lda #6
ldy IRQInd+1
ldx IRQInd+2
jsr SETVBV
; Restore system stuff ; Restore system stuff
NoIRQ2: ldx spsave ldx spsave
txs ; Restore stack pointer txs ; Restore stack pointer
; Restore left margin ; Restore left margin
@@ -166,28 +143,17 @@ L2: lda zpsave,x
rts rts
; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
; Data
.data
IRQInd: jmp $0000
; *** end of main startup code ; *** end of main startup code
; ------------------------------------------------------------------------
.segment "ZPSAVE" .segment "ZPSAVE"
zpsave: .res zpspace zpsave: .res zpspace
.bss ; ------------------------------------------------------------------------
.bss
spsave: .res 1 spsave: .res 1
appmsav: .res 1 appmsav: .res 1

49
libsrc/atari/irq.s Normal file
View File

@@ -0,0 +1,49 @@
;
; IRQ handling (ATARI version)
;
.export initirq, doneirq
.import callirq
.include "atari.inc"
; ------------------------------------------------------------------------
.segment "INIT"
initirq:
lda VVBLKI
ldx VVBLKI+1
sta IRQInd+1
stx IRQInd+2
lda #6
ldy #<IRQStub
ldx #>IRQStub
jsr SETVBV
rts
; ------------------------------------------------------------------------
.code
doneirq:
lda #6
ldy IRQInd+1
ldx IRQInd+2
jsr SETVBV
rts
; ------------------------------------------------------------------------
.segment "LOWCODE"
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
.data
IRQInd: jmp $0000

View File

@@ -81,6 +81,7 @@ OBJS = _scrsize.o \
gotox.o \ gotox.o \
gotoxy.o \ gotoxy.o \
gotoy.o \ gotoy.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

View File

@@ -7,15 +7,13 @@
.export _exit .export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib .import initlib, donelib
.import callmain, zerobss, callirq .import callmain, zerobss
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__ .import __RAM_START__, __RAM_SIZE__
.import __ZPSAVE_LOAD__, __STACKSIZE__ .import __ZPSAVE_LOAD__, __STACKSIZE__
.include "zeropage.inc" .include "zeropage.inc"
.include "atmos.inc" .include "atmos.inc"
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Oric tape header ; Oric tape header
@@ -70,24 +68,9 @@ L1: lda sp,x
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1 ; Set argument stack ptr sta sp+1 ; Set argument stack ptr
; If we have IRQ functions, chain our stub into the IRQ vector
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
; Call module constructors ; Call module constructors
NoIRQ1: jsr initlib jsr initlib
; Push arguments and call main() ; Push arguments and call main()
@@ -97,21 +80,9 @@ NoIRQ1: jsr initlib
_exit: jsr donelib ; Run module destructors _exit: jsr donelib ; Run module destructors
; Reset the IRQ vector if we chained it.
pha ; Save the return code on stack
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ2
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
; Restore system stuff ; Restore system stuff
NoIRQ2: ldx spsave ldx spsave
txs txs
lda stsave lda stsave
sta STATUS sta STATUS
@@ -129,34 +100,13 @@ L2: lda zpsave,x
rts rts
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub:
cld ; Just to be sure
pha
txa
pha
tya
pha
jsr callirq ; Call the functions
pla
tay
pla
tax
pla
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
; Data
.data
IRQInd: jmp $0000
.segment "ZPSAVE" .segment "ZPSAVE"
zpsave: .res zpspace zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss .bss
spsave: .res 1 spsave: .res 1

64
libsrc/atmos/irq.s Normal file
View File

@@ -0,0 +1,64 @@
;
; IRQ handling (Oric version)
;
.export initirq, doneirq
.import callirq
.include "atmos.inc"
; ------------------------------------------------------------------------
.segment "INIT"
initirq:
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.code
doneirq:
beq NoIRQ2
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.segment "LOWCODE"
IRQStub:
cld ; Just to be sure
pha
txa
pha
tya
pha
jsr callirq ; Call the functions
pla
tay
pla
tax
pla
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
.data
IRQInd: jmp $0000

View File

@@ -77,6 +77,7 @@ OBJS = _scrsize.o \
devnum.o \ devnum.o \
fast.o \ fast.o \
get_tv.o \ get_tv.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

View File

@@ -4,11 +4,10 @@
.export _exit .export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import callirq, initlib, donelib .import initlib, donelib
.import zerobss .import zerobss
.import push0, callmain .import push0, callmain
.import RESTOR, BSOUT, CLRCH .import RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__, __STACKSIZE__ .import __RAM_START__, __RAM_SIZE__, __STACKSIZE__
.importzp ST .importzp ST
@@ -16,11 +15,6 @@
.include "c128.inc" .include "c128.inc"
; ------------------------------------------------------------------------
; Constants
IRQInd = $2FD ; JMP $0000 - used as indirect IRQ vector
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Startup code ; Startup code
@@ -67,24 +61,9 @@ L1: lda sp,x
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1 ; Set argument stack ptr sta sp+1 ; Set argument stack ptr
; If we have IRQ functions, chain our stub into the IRQ vector
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
; Call module constructors ; Call module constructors
NoIRQ1: jsr initlib jsr initlib
; Set the bank for the file name to our execution bank. We must do this, ; Set the bank for the file name to our execution bank. We must do this,
; *after* calling constructors, because some of them may depend on the ; *after* calling constructors, because some of them may depend on the
@@ -99,23 +78,12 @@ NoIRQ1: jsr initlib
; Back from main (this is also the _exit entry). Run module destructors ; Back from main (this is also the _exit entry). Run module destructors
_exit: jsr donelib _exit: pha ; Save the return code on stack
jsr donelib
; Reset the IRQ vector if we chained it.
pha ; Save the return code on stack
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ2
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
; Copy back the zero page stuff ; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1 ldx #zpspace-1
L2: lda zpsave,x L2: lda zpsave,x
sta sp,x sta sp,x
dex dex
@@ -137,30 +105,6 @@ L2: lda zpsave,x
rts rts
; ------------------------------------------------------------------------
; The C128 has ROM parallel to the RAM starting from $4000. The startup code
; above will change this setting so that we have RAM from $0000-$BFFF. This
; works quite well with the exception of interrupts: The interrupt handler
; is in ROM, and the ROM switches back to the ROM configuration, which means
; that parts of our program may not be accessible. To solve this, we place
; the following code into a special segment called "LOWCODE" which will be
; placed just above the startup code, so it goes into a RAM area that is
; not banked.
.segment "LOWCODE"
IRQStub:
cld ; Just to be sure
lda MMU_CR ; Get old register value
pha ; And save on stack
lda #MMU_CFG_CC65 ; Bank 0 with kernal ROM
sta MMU_CR
jsr callirq ; Call the functions
pla ; Get old register value
sta MMU_CR
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Data ; Data
@@ -168,9 +112,9 @@ IRQStub:
zpsave: .res zpspace zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss .bss
spsave: .res 1 spsave: .res 1
mmusave:.res 1 mmusave:.res 1

63
libsrc/c128/irq.s Normal file
View File

@@ -0,0 +1,63 @@
;
; IRQ handling (C128 version)
;
.export initirq, doneirq
.import callirq
.include "c128.inc"
IRQInd = $2FD ; JMP $0000 - used as indirect IRQ vector
; ------------------------------------------------------------------------
.segment "INIT"
initirq:
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.code
doneirq:
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
; The C128 has ROM parallel to the RAM starting from $4000. The startup code
; above will change this setting so that we have RAM from $0000-$BFFF. This
; works quite well with the exception of interrupts: The interrupt handler
; is in ROM, and the ROM switches back to the ROM configuration, which means
; that parts of our program may not be accessible. To solve this, we place
; the following code into a special segment called "LOWCODE" which will be
; placed just above the startup code, so it goes into a RAM area that is
; not banked.
.segment "LOWCODE"
IRQStub:
cld ; Just to be sure
lda MMU_CR ; Get old register value
pha ; And save on stack
lda #MMU_CFG_CC65 ; Bank 0 with kernal ROM
sta MMU_CR
jsr callirq ; Call the functions
pla ; Get old register value
sta MMU_CR
jmp IRQInd ; Jump to the saved IRQ vector

View File

@@ -68,6 +68,7 @@ OBJS = _scrsize.o \
crt0.o \ crt0.o \
devnum.o \ devnum.o \
get_tv.o \ get_tv.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

View File

@@ -7,16 +7,14 @@
.export _exit .export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq .import initlib, donelib
.import callmain, zerobss .import callmain, zerobss
.import MEMTOP, RESTOR, BSOUT, CLRCH .import MEMTOP, RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.importzp ST .importzp ST
.include "zeropage.inc" .include "zeropage.inc"
.include "plus4.inc" .include "plus4.inc"
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Startup code ; Startup code
@@ -55,24 +53,9 @@ L1: lda sp,x
MemOk: stx sp MemOk: stx sp
sty sp+1 ; set argument stack ptr sty sp+1 ; set argument stack ptr
; If we have IRQ functions, chain our stub into the IRQ vector
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
; Call module constructors ; Call module constructors
NoIRQ1: jsr initlib jsr initlib
; Push arguments and call main() ; Push arguments and call main()
@@ -83,21 +66,9 @@ NoIRQ1: jsr initlib
_exit: pha ; Save the return code on stack _exit: pha ; Save the return code on stack
jsr donelib ; Run module destructors jsr donelib ; Run module destructors
; Reset the IRQ vector if we chained it.
pha ; Save the return code on stack
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ2
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
; Copy back the zero page stuff ; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1 ldx #zpspace-1
L2: lda zpsave,x L2: lda zpsave,x
sta sp,x sta sp,x
dex dex
@@ -118,26 +89,13 @@ L2: lda zpsave,x
rts rts
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
; Data
.data
IRQInd: jmp $0000
.segment "ZPSAVE" .segment "ZPSAVE"
zpsave: .res zpspace zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss .bss
spsave: .res 1 spsave: .res 1

53
libsrc/c16/irq.s Normal file
View File

@@ -0,0 +1,53 @@
;
; IRQ handling (C16 version)
;
.export _exit
.import callirq
.include "plus4.inc"
; ------------------------------------------------------------------------
.segment "INIT"
initirq:
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.code
doneirq:
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.segment "LOWCODE"
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
.data
IRQInd: jmp $0000

View File

@@ -76,6 +76,7 @@ OBJS = _scrsize.o \
devnum.o \ devnum.o \
get_ostype.o \ get_ostype.o \
get_tv.o \ get_tv.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

View File

@@ -4,11 +4,10 @@
.export _exit .export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq .import initlib, donelib
.import zerobss .import zerobss
.import callmain .import callmain
.import RESTOR, BSOUT, CLRCH .import RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__ ; Linker generated .import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import __STACKSIZE__ ; Linker generated .import __STACKSIZE__ ; Linker generated
.importzp ST .importzp ST
@@ -62,24 +61,9 @@ L1: lda sp,x
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1 ; Set argument stack ptr sta sp+1 ; Set argument stack ptr
; If we have IRQ functions, chain our stub into the IRQ vector
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
; Call module constructors ; Call module constructors
NoIRQ1: jsr initlib jsr initlib
; Push arguments and call main ; Push arguments and call main
@@ -87,24 +71,12 @@ NoIRQ1: jsr initlib
; Back from main (This is also the _exit entry). Run module destructors ; Back from main (This is also the _exit entry). Run module destructors
_exit: jsr donelib _exit: pha ; Save the return code on stack
jsr donelib
; Reset the IRQ vector if we chained it.
pha ; Save the return code on stack
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ2
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
; Copy back the zero page stuff ; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1 ldx #zpspace-1
L2: lda zpsave,x L2: lda zpsave,x
sta sp,x sta sp,x
dex dex
@@ -126,21 +98,9 @@ L2: lda zpsave,x
rts rts
; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Data ; Data
.data
IRQInd: jmp $0000
.segment "ZPSAVE" .segment "ZPSAVE"
zpsave: .res zpspace zpsave: .res zpspace

53
libsrc/c64/irq.s Normal file
View File

@@ -0,0 +1,53 @@
;
; IRQ handling (C64 version)
;
.export initirq, doneirq
.import callirq
.include "c64.inc"
; ------------------------------------------------------------------------
.segment "INIT"
initirq:
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.code
doneirq:
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.segment "LOWCODE"
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
.data
IRQInd: jmp $0000

View File

@@ -68,6 +68,7 @@ OBJS = _scrsize.o \
crt0.o \ crt0.o \
devnum.o \ devnum.o \
extzp.o \ extzp.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

9
libsrc/cbm510/irq.s Normal file
View File

@@ -0,0 +1,9 @@
;
; IRQ handling (CBM 500 version)
;
.export initirq, doneirq
initirq:
doneirq:
rts

View File

@@ -70,6 +70,7 @@ OBJS = _scrsize.o \
devnum.o \ devnum.o \
extzp.o \ extzp.o \
get_tv.o \ get_tv.o \
irq.o \
kbhit.o \ kbhit.o \
kclose.o \ kclose.o \
kernal.o \ kernal.o \

9
libsrc/cbm610/irq.s Normal file
View File

@@ -0,0 +1,9 @@
;
; IRQ handling (CBM 600/700 version)
;
.export initirq, doneirq
initirq:
doneirq:
rts

View File

@@ -79,6 +79,7 @@ OBJS = bllhdr.o \
exec.o \ exec.o \
exehdr.o \ exehdr.o \
extzp.o \ extzp.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

View File

@@ -15,19 +15,18 @@
; on the front of the fully linked binary (see EXEHDR segment.) ; on the front of the fully linked binary (see EXEHDR segment.)
; ;
.include "lynx.inc"
.export _exit .export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import callirq, initlib, donelib .import initlib, donelib
.import zerobss .import zerobss
.import callmain .import callmain
.import _main .import _main
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__, __STACKSIZE__ .import __RAM_START__, __RAM_SIZE__, __STACKSIZE__
.include "zeropage.inc" .include "zeropage.inc"
.include "extzp.inc" .include "extzp.inc"
.include "lynx.inc"
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Mikey and Suzy init data, reg offsets and data ; Mikey and Suzy init data, reg offsets and data
@@ -40,7 +39,6 @@ SuzyInitData: .byte $7f,$7f,$00,$00,$24,$f3,$01
MikeyInitReg: .byte $00,$01,$08,$09,$20,$28,$30,$38,$44,$50,$8a,$8b,$8c,$92,$93 MikeyInitReg: .byte $00,$01,$08,$09,$20,$28,$30,$38,$44,$50,$8a,$8b,$8c,$92,$93
MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$29 MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$29
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Actual code ; Actual code
@@ -115,26 +113,15 @@ sloop: ldy SuzyInitReg,x
lda #$24 lda #$24
sta __sprsys sta __sprsys
cli
; Clear the BSS data ; Clear the BSS data
jsr zerobss jsr zerobss
; If we have IRQ functions, set the IRQ vector
; as Lynx is a console there is not much point in releasing the IRQ
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda #<IRQStub
ldx #>IRQStub
sei
sta INTVECTL
stx INTVECTH
cli
; Call module constructors ; Call module constructors
NoIRQ1: jsr initlib jsr initlib
; Push arguments and call main ; Push arguments and call main
@@ -147,19 +134,3 @@ _exit: jsr donelib ; Run module destructors
; Endless loop ; Endless loop
noret: bra noret noret: bra noret
.segment "CODE"
IRQStub:
phy
phx
pha
cld
jsr callirq
lda INTSET
sta INTRST
pla
plx
ply
rti

46
libsrc/lynx/irq.s Normal file
View File

@@ -0,0 +1,46 @@
;
; IRQ handling (Lynx version)
;
.export initirq, doneirq
.import callirq
.include "lynx.inc"
; ------------------------------------------------------------------------
.segment "INIT"
initirq:
lda #<IRQStub
ldx #>IRQStub
sei
sta INTVECTL
stx INTVECTH
cli
rts
; ------------------------------------------------------------------------
.code
doneirq:
; as Lynx is a console there is not much point in releasing the IRQ
rts
; ------------------------------------------------------------------------
.segment "LOWCODE"
IRQStub:
phy
phx
pha
cld
jsr callirq
lda INTSET
sta INTRST
pla
plx
ply
rti

View File

@@ -62,6 +62,7 @@ OBJS = _scrsize.o \
crt0.o \ crt0.o \
devnum.o \ devnum.o \
get_tv.o \ get_tv.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

View File

@@ -4,11 +4,10 @@
.export _exit .export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq .import initlib, donelib
.import zerobss, push0 .import zerobss, push0
.import callmain .import callmain
.import CLRCH, BSOUT .import CLRCH, BSOUT
.import __INTERRUPTOR_COUNT__
.importzp ST .importzp ST
.include "zeropage.inc" .include "zeropage.inc"
@@ -58,24 +57,9 @@ L1: lda sp,x
lda MEMSIZE+1 lda MEMSIZE+1
sta sp+1 ; Set argument stack ptr sta sp+1 ; Set argument stack ptr
; If we have IRQ functions, chain our stub into the IRQ vector
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
; Call module constructors ; Call module constructors
NoIRQ1: jsr initlib jsr initlib
; Push arguments and call main() ; Push arguments and call main()
@@ -86,20 +70,9 @@ NoIRQ1: jsr initlib
_exit: pha ; Save the return code on stack _exit: pha ; Save the return code on stack
jsr donelib jsr donelib
; Reset the IRQ vector if we chained it.
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ2
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
; Copy back the zero page stuff ; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1 ldx #zpspace-1
L2: lda zpsave,x L2: lda zpsave,x
sta sp,x sta sp,x
dex dex
@@ -120,26 +93,14 @@ L2: lda zpsave,x
rts rts
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
; Data
.data
IRQInd: jmp $0000
.segment "ZPSAVE" .segment "ZPSAVE"
zpsave: .res zpspace zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss .bss
spsave: .res 1 spsave: .res 1
mmusave:.res 1 mmusave:.res 1

53
libsrc/pet/irq.s Normal file
View File

@@ -0,0 +1,53 @@
;
; IRQ handling (PET version)
;
.export initirq, doneirq
.import callirq
.include "pet.inc"
; ------------------------------------------------------------------------
.segment "INIT"
initirq:
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.code
doneirq:
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.segment "LOWCODE"
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
.data
IRQInd: jmp $0000

View File

@@ -68,6 +68,7 @@ OBJS = _scrsize.o \
crt0.o \ crt0.o \
devnum.o \ devnum.o \
get_tv.o \ get_tv.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kacptr.o \ kacptr.o \

9
libsrc/plus4/irq.s Normal file
View File

@@ -0,0 +1,9 @@
;
; IRQ handling (Plus/4 version)
;
.export initirq, doneirq
initirq:
doneirq:
rts

View File

@@ -29,11 +29,16 @@
.export callirq .export callirq
.export callirq_y ; Same but with Y preloaded .export callirq_y ; Same but with Y preloaded
.export __CALLIRQ__ : absolute = 1
.constructor irq_init, 10
.destructor irq_done, 10
.export __CALLIRQ__: absolute = 1
.import __INTERRUPTOR_TABLE__, __INTERRUPTOR_COUNT__ .import __INTERRUPTOR_TABLE__, __INTERRUPTOR_COUNT__
.import initirq
.import doneirq
.code irq_init := initirq
irq_done := doneirq
; -------------------------------------------------------------------------- ; --------------------------------------------------------------------------
; Call all IRQ routines. The function needs to use self modifying code and ; Call all IRQ routines. The function needs to use self modifying code and
@@ -60,5 +65,3 @@ jmpvec: jsr $FFFF ; Patched at runtime
index: ldy #$FF ; Patched at runtime index: ldy #$FF ; Patched at runtime
bne loop bne loop
done: rts done: rts

View File

@@ -61,6 +61,7 @@ OBJS = _scrsize.o \
cputc.o \ cputc.o \
devnum.o \ devnum.o \
get_tv.o \ get_tv.o \
irq.o \
joy_stat_stddrv.o \ joy_stat_stddrv.o \
joy_stddrv.o \ joy_stddrv.o \
kbhit.o \ kbhit.o \

View File

@@ -4,11 +4,10 @@
.export _exit .export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq .import initlib, donelib
.import zerobss, push0 .import zerobss, push0
.import callmain .import callmain
.import RESTOR, BSOUT, CLRCH .import RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__ ; Linker generated .import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import __STACKSIZE__ ; Linker generated .import __STACKSIZE__ ; Linker generated
.importzp ST .importzp ST
@@ -50,24 +49,9 @@ L1: lda sp,x
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1 ; Set argument stack ptr sta sp+1 ; Set argument stack ptr
; If we have IRQ functions, chain our stub into the IRQ vector
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
; Call module constructors ; Call module constructors
NoIRQ1: jsr initlib jsr initlib
; Push arguments and call main() ; Push arguments and call main()
@@ -75,23 +59,12 @@ NoIRQ1: jsr initlib
; Back from main (This is also the _exit entry). Run module destructors ; Back from main (This is also the _exit entry). Run module destructors
_exit: jsr donelib _exit: pha ; Save the return code on stack
jsr donelib
; Reset the IRQ vector if we chained it.
pha ; Save the return code on stack
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ2
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
; Copy back the zero page stuff ; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1 ldx #zpspace-1
L2: lda zpsave,x L2: lda zpsave,x
sta sp,x sta sp,x
dex dex
@@ -111,26 +84,14 @@ L2: lda zpsave,x
rts rts
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
; Data
.data
IRQInd: jmp $0000
.segment "ZPSAVE" .segment "ZPSAVE"
zpsave: .res zpspace zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss .bss
spsave: .res 1 spsave: .res 1

53
libsrc/vic20/irq.s Normal file
View File

@@ -0,0 +1,53 @@
;
; IRQ handling (Vic20 version)
;
.export initirq, doneirq
.import callirq
.include "vic20.inc"
; ------------------------------------------------------------------------
.segment "INIT"
initirq:
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.code
doneirq:
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
rts
; ------------------------------------------------------------------------
.segment "LOWCODE"
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
.data
IRQInd: jmp $0000