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

@@ -5,75 +5,72 @@
; ;
.export _exit, done, return .export _exit, done, return
.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:
; "For maximum interrupt efficiency, a system program should not ; "For maximum interrupt efficiency, a system program should not
; use more than the upper 3/4 of the stack." ; use more than the upper 3/4 of the stack."
ldx #$FF ldx #$FF
txs ; Init stack pointer txs ; Init stack pointer
; Switch in LC bank 2 for W/O ; Switch in LC bank 2 for W/O
bit $C081 bit $C081
bit $C081 bit $C081
; Set source start address ; Set source start address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__) lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__) ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
sta $9B sta $9B
sty $9C sty $9C
; Set source last address ; Set source last address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__) lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__) ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
sta $96 sta $96
sty $97 sty $97
; Set destination last address ; Set destination last address
lda #<__LC_LAST__ lda #<__LC_LAST__
ldy #>__LC_LAST__ ldy #>__LC_LAST__
sta $94 sta $94
sty $95 sty $95
; Call into Applesoft Block Transfer Utility - which handles zero ; Call into Applesoft Block Transfer Utility - which handles zero
; sized blocks well - to move content of the LC memory area ; sized blocks well - to move content of the LC memory area
jsr $D396 ; BLTU + 3 jsr $D396 ; BLTU + 3
; Set source start address ; Set source start address
lda #<__ZPSAVE_RUN__ lda #<__ZPSAVE_RUN__
ldy #>__ZPSAVE_RUN__ ldy #>__ZPSAVE_RUN__
sta $9B sta $9B
sty $9C sty $9C
; Set source last address ; Set source last address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__) lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__) ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
sta $96 sta $96
sty $97 sty $97
; Set destination last address ; Set destination last address
lda #<(__INIT_RUN__ + __INIT_SIZE__) lda #<(__INIT_RUN__ + __INIT_SIZE__)
ldy #>(__INIT_RUN__ + __INIT_SIZE__) ldy #>(__INIT_RUN__ + __INIT_SIZE__)
sta $94 sta $94
sty $95 sty $95
; Call into Applesoft Block Transfer Utility - which handles moving ; Call into Applesoft Block Transfer Utility - which handles moving
; overlapping blocks upwards well - to move the INIT segment ; overlapping blocks upwards well - to move the INIT segment
jsr $D396 ; BLTU + 3 jsr $D396 ; BLTU + 3
; Delegate all further processing to keep the STARTUP segment small ; Delegate all further processing to keep the STARTUP segment small
jsr init jsr init
@@ -81,24 +78,14 @@
; Avoid re-entrance of donelib. This is also the _exit entry ; Avoid re-entrance of donelib. This is also the _exit entry
_exit: ldx #<exit _exit: ldx #<exit
lda #>exit lda #>exit
jsr reset ; Setup RESET vector jsr reset ; Setup RESET vector
; Switch in ROM in case it wasn't already switched in by a RESET ; Switch in ROM in case it wasn't already switched in by a RESET
bit $C082 bit $C082
; 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
@@ -148,11 +133,11 @@ init: ldx #zpspace-1
; address of a routine that ... closes the files." ; address of a routine that ... closes the files."
ldx #<_exit ldx #<_exit
lda #>_exit lda #>_exit
jsr reset ; Setup RESET vector jsr reset ; Setup RESET vector
; Check for ProDOS ; Check for ProDOS
ldy $BF00 ; MLI call entry point ldy $BF00 ; MLI call entry point
cpy #$4C ; Is MLI present? (JMP opcode) cpy #$4C ; Is MLI present? (JMP opcode)
bne basic bne basic
; Check ProDOS system bit map ; Check ProDOS system bit map
@@ -179,80 +164,20 @@ basic: lda HIMEM
: sta sp : sta sp
stx sp+1 stx sp+1
; Check for interruptors ; Enable interrupts as old ProDOS versions (i.e. 1.1.1)
lda #<__INTERRUPTOR_COUNT__ ; jump to SYS and BIN programs with interrupts disabled
beq :+ cli
; 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)
; jump to SYS and BIN programs with interrupts disabled
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
; 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,37 +191,24 @@ 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
q_param:.byte $04 ; param_count q_param:.byte $04 ; param_count
.byte $00 ; quit_type .byte $00 ; quit_type
.word $0000 ; reserved .word $0000 ; reserved
.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,8 +4,8 @@
; void rebootafterexit (void); ; void rebootafterexit (void);
; ;
.constructor initreboot .constructor initreboot, 11
.export _rebootafterexit .export _rebootafterexit
.import done, return .import done, return
_rebootafterexit := return _rebootafterexit := 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

@@ -2,124 +2,92 @@
; Startup code for cc65 (C128 version) ; Startup code for cc65 (C128 version)
; ;
.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
.include "zeropage.inc" .include "zeropage.inc"
.include "c128.inc" .include "c128.inc"
; ------------------------------------------------------------------------
; Constants
IRQInd = $2FD ; JMP $0000 - used as indirect IRQ vector
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Startup code ; Startup code
.segment "STARTUP" .segment "STARTUP"
Start: Start:
; Switch to the second charset ; Switch to the second charset
lda #14 lda #14
jsr BSOUT jsr BSOUT
; Before doing anything else, we have to setup our banking configuration. ; Before doing anything else, we have to setup our banking configuration.
; Otherwise just the lowest 16K are actually RAM. Writing through the ROM ; Otherwise just the lowest 16K are actually RAM. Writing through the ROM
; to the underlying RAM works, but it is bad style. ; to the underlying RAM works, but it is bad style.
lda MMU_CR ; Get current memory configuration... lda MMU_CR ; Get current memory configuration...
pha ; ...and save it for later pha ; ...and save it for later
lda #MMU_CFG_CC65 ; Bank0 with kernal ROM lda #MMU_CFG_CC65 ; Bank0 with kernal ROM
sta MMU_CR sta MMU_CR
; Save the zero page locations we need ; Save the zero page locations we need
ldx #zpspace-1 ldx #zpspace-1
L1: lda sp,x L1: lda sp,x
sta zpsave,x sta zpsave,x
dex dex
bpl L1 bpl L1
; Clear the BSS data ; Clear the BSS data
jsr zerobss jsr zerobss
; Save system stuff and setup the stack ; Save system stuff and setup the stack
pla ; Get MMU setting pla ; Get MMU setting
sta mmusave sta mmusave
tsx tsx
stx spsave ; Save the system stack pointer stx spsave ; Save the system stack pointer
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp sta sp
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
; original value of this register. ; original value of this register.
lda #0 lda #0
sta FNAM_BANK sta FNAM_BANK
; Push arguments and call main() ; Push arguments and call main()
jsr callmain jsr callmain
; 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
bpl L2 bpl L2
; Place the program return code into ST ; Place the program return code into ST
@@ -128,49 +96,25 @@ L2: lda zpsave,x
; Reset the stack and the memory configuration ; Reset the stack and the memory configuration
ldx spsave ldx spsave
txs txs
ldx mmusave ldx mmusave
stx MMU_CR stx MMU_CR
; Done, return to BASIC ; Done, return to BASIC
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
.segment "ZPSAVE" .segment "ZPSAVE"
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

@@ -6,31 +6,29 @@
; ;
.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
.segment "STARTUP" .segment "STARTUP"
Start: Start:
; Save the zero page locations we need ; Save the zero page locations we need
ldx #zpspace-1 ldx #zpspace-1
L1: lda sp,x L1: lda sp,x
sta zpsave,x sta zpsave,x
dex dex
bpl L1 bpl L1
; Switch to second charset ; Switch to second charset
@@ -43,65 +41,38 @@ L1: lda sp,x
; Save system stuff and setup the stack ; Save system stuff and setup the stack
tsx tsx
stx spsave ; save system stk ptr stx spsave ; save system stk ptr
sec sec
jsr MEMTOP ; Get top memory jsr MEMTOP ; Get top memory
cpy #$80 ; We can only use the low 32K :-( cpy #$80 ; We can only use the low 32K :-(
bcc MemOk bcc MemOk
ldy #$80 ldy #$80
ldx #$00 ldx #$00
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()
jsr callmain jsr callmain
; Call module destructors. This is also the _exit entry. ; Call module destructors. This is also the _exit entry.
_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
bpl L2 bpl L2
; Store the return code into ST ; Store the return code into ST
@@ -118,26 +89,13 @@ L2: lda zpsave,x
rts rts
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub: .segment "ZPSAVE"
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"
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

@@ -3,34 +3,33 @@
; ;
.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
.include "zeropage.inc" .include "zeropage.inc"
.include "c64.inc" .include "c64.inc"
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Startup code ; Startup code
.segment "STARTUP" .segment "STARTUP"
Start: Start:
; Save the zero page locations we need ; Save the zero page locations we need
ldx #zpspace-1 ldx #zpspace-1
L1: lda sp,x L1: lda sp,x
sta zpsave,x sta zpsave,x
dex dex
bpl L1 bpl L1
; Switch to second charset ; Switch to second charset
@@ -40,9 +39,9 @@ L1: lda sp,x
; Switch off the BASIC ROM ; Switch off the BASIC ROM
lda $01 lda $01
pha ; Remember the value pha ; Remember the value
and #$F8 and #$F8
ora #$06 ; Enable kernal+I/O, disable basic ora #$06 ; Enable kernal+I/O, disable basic
sta $01 sta $01
; Clear the BSS data ; Clear the BSS data
@@ -51,64 +50,37 @@ L1: lda sp,x
; Save system settings and setup the stack ; Save system settings and setup the stack
pla pla
sta mmusave ; Save the memory configuration sta mmusave ; Save the memory configuration
tsx tsx
stx spsave ; Save the system stack ptr stx spsave ; Save the system stack ptr
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp sta sp
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
jsr callmain jsr callmain
; 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
bpl L2 bpl L2
; Place the program return code into ST ; Place the program return code into ST
@@ -117,31 +89,19 @@ L2: lda zpsave,x
; Restore system stuff ; Restore system stuff
ldx spsave ldx spsave
txs ; Restore stack pointer txs ; Restore stack pointer
ldx mmusave ldx mmusave
stx $01 ; Restore memory configuration stx $01 ; Restore memory configuration
; Back to basic ; Back to basic
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 .segment "ZPSAVE"
IRQInd: jmp $0000
.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,31 +15,29 @@
; 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
.rodata .rodata
SuzyInitReg: .byte $28,$2a,$04,$06,$92,$83,$90 SuzyInitReg: .byte $28,$2a,$04,$06,$92,$83,$90
SuzyInitData: .byte $7f,$7f,$00,$00,$24,$f3,$01 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
MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$29
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
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Actual code ; Actual code
@@ -50,116 +48,89 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2
sei sei
cld cld
ldx #$FF ldx #$FF
txs txs
; init bank switching ; init bank switching
lda #$C lda #$C
sta MAPCTL ; $FFF9 sta MAPCTL ; $FFF9
; disable all timer interrupts ; disable all timer interrupts
lda #$80 lda #$80
trb TIM0CTLA trb TIM0CTLA
trb TIM1CTLA trb TIM1CTLA
trb TIM2CTLA trb TIM2CTLA
trb TIM3CTLA trb TIM3CTLA
trb TIM5CTLA trb TIM5CTLA
trb TIM6CTLA trb TIM6CTLA
trb TIM7CTLA trb TIM7CTLA
; disable TX/RX IRQ, set to 8E1 ; disable TX/RX IRQ, set to 8E1
lda #%11101 lda #%11101
sta SERCTL sta SERCTL
; clear all pending interrupts ; clear all pending interrupts
lda INTSET lda INTSET
sta INTRST sta INTRST
; setup the stack ; setup the stack
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp sta sp
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1 sta sp+1
; Init Mickey ; Init Mickey
ldx #.sizeof(MikeyInitReg)-1 ldx #.sizeof(MikeyInitReg)-1
mloop: ldy MikeyInitReg,x mloop: ldy MikeyInitReg,x
lda MikeyInitData,x lda MikeyInitData,x
sta $fd00,y sta $fd00,y
dex dex
bpl mloop bpl mloop
; these are RAM-shadows of read only regs ; these are RAM-shadows of read only regs
ldx #$1b ldx #$1b
stx __iodat stx __iodat
dex ; $1A dex ; $1A
stx __iodir stx __iodir
ldx #$d ldx #$d
stx __viddma stx __viddma
; Init Suzy ; Init Suzy
ldx #.sizeof(SuzyInitReg)-1 ldx #.sizeof(SuzyInitReg)-1
sloop: ldy SuzyInitReg,x sloop: ldy SuzyInitReg,x
lda SuzyInitData,x lda SuzyInitData,x
sta $fc00,y sta $fc00,y
dex dex
bpl sloop bpl sloop
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
jsr callmain jsr callmain
; Call module destructors. This is also the _exit entry. ; Call module destructors. This is also the _exit entry.
_exit: jsr donelib ; Run module destructors _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

@@ -2,33 +2,32 @@
; Startup code for cc65 (PET version) ; Startup code for cc65 (PET version)
; ;
.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"
.include "pet.inc" .include "pet.inc"
.include "../cbm/cbm.inc" .include "../cbm/cbm.inc"
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Startup code ; Startup code
.segment "STARTUP" .segment "STARTUP"
Start: Start:
; Save the zero page locations we need ; Save the zero page locations we need
ldx #zpspace-1 ldx #zpspace-1
L1: lda sp,x L1: lda sp,x
sta zpsave,x sta zpsave,x
dex dex
bpl L1 bpl L1
; Switch to second charset. The routine that is called by BSOUT to switch the ; Switch to second charset. The routine that is called by BSOUT to switch the
; character set will use FNLEN as temporary storage - YUCK! Since the ; character set will use FNLEN as temporary storage - YUCK! Since the
@@ -36,13 +35,13 @@ L1: lda sp,x
; information, we need to save and restore it here. ; information, we need to save and restore it here.
; Thanks to Stefan Haubenthal for this information! ; Thanks to Stefan Haubenthal for this information!
lda FNLEN lda FNLEN
pha ; Save FNLEN pha ; Save FNLEN
lda #14 lda #14
; sta $E84C ; See PET FAQ ; sta $E84C ; See PET FAQ
jsr BSOUT jsr BSOUT
pla pla
sta FNLEN ; Restore FNLEN sta FNLEN ; Restore FNLEN
; Clear the BSS data ; Clear the BSS data
@@ -50,60 +49,34 @@ L1: lda sp,x
; Save system stuff and setup the stack ; Save system stuff and setup the stack
tsx tsx
stx spsave ; Save the system stack ptr stx spsave ; Save the system stack ptr
lda MEMSIZE lda MEMSIZE
sta sp sta sp
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()
jsr callmain jsr callmain
; Call module destructors. This is also the _exit entry. ; Call module destructors. This is also the _exit entry.
_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
bpl L2 bpl L2
; Store the program return code into ST ; Store the program return code into ST
@@ -113,33 +86,21 @@ L2: lda zpsave,x
; Restore the stack pointer ; Restore the stack pointer
ldx spsave ldx spsave
txs ; Restore stack pointer txs ; Restore stack pointer
; Back to basic ; Back to basic
rts rts
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub: .segment "ZPSAVE"
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"
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

@@ -27,13 +27,18 @@
; entries. ; entries.
; ;
.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
@@ -51,14 +56,12 @@ callirq_y:
loop: dey loop: dey
lda __INTERRUPTOR_TABLE__,y lda __INTERRUPTOR_TABLE__,y
sta jmpvec+2 ; Modify code below sta jmpvec+2 ; Modify code below
dey dey
lda __INTERRUPTOR_TABLE__,y lda __INTERRUPTOR_TABLE__,y
sta jmpvec+1 ; Modify code below sta jmpvec+1 ; Modify code below
sty index+1 ; Modify code below sty index+1 ; Modify code below
jmpvec: jsr $FFFF ; Patched at runtime jmpvec: jsr $FFFF ; Patched at runtime
bcs done ; Bail out if interrupt handled bcs done ; Bail out if interrupt handled
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

@@ -3,33 +3,32 @@
; ;
.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
.include "zeropage.inc" .include "zeropage.inc"
.include "vic20.inc" .include "vic20.inc"
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Startup code ; Startup code
.segment "STARTUP" .segment "STARTUP"
Start: Start:
; Save the zero page locations we need ; Save the zero page locations we need
ldx #zpspace-1 ldx #zpspace-1
L1: lda sp,x L1: lda sp,x
sta zpsave,x sta zpsave,x
dex dex
bpl L1 bpl L1
; Switch to second charset ; Switch to second charset
@@ -42,60 +41,34 @@ L1: lda sp,x
; Save system stuff and setup the stack ; Save system stuff and setup the stack
tsx tsx
stx spsave ; Save the system stack ptr stx spsave ; Save the system stack ptr
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp sta sp
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()
jsr callmain jsr callmain
; 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
bpl L2 bpl L2
; Place the program return code into ST ; Place the program return code into ST
@@ -104,33 +77,21 @@ L2: lda zpsave,x
; Restore the stack pointer ; Restore the stack pointer
ldx spsave ldx spsave
txs txs
; Back to basic ; Back to basic
rts rts
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub: .segment "ZPSAVE"
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"
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