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 \
initcwd.o \
iobuf.o \
irq.o \
isdevice.o \
joy_stat_stddrv.o \
joy_stddrv.o \

View file

@ -5,75 +5,72 @@
;
.export _exit, done, return
.export __STARTUP__ : absolute = 1 ; Mark as startup
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import zerobss
.import initlib, donelib
.import callmain, callirq
.import __LC_START__, __LC_LAST__ ; Linker generated
.import __INIT_RUN__, __INIT_SIZE__ ; Linker generated
.import __ZPSAVE_RUN__ ; Linker generated
.import __INTERRUPTOR_COUNT__ ; Linker generated
.import initlib, donelib
.import callmain
.import __LC_START__, __LC_LAST__ ; Linker generated
.import __INIT_RUN__, __INIT_SIZE__ ; Linker generated
.import __ZPSAVE_RUN__ ; Linker generated
.include "zeropage.inc"
.include "apple2.inc"
; ------------------------------------------------------------------------
.segment "STARTUP"
; ProDOS TechRefMan, chapter 5.2.1:
; "For maximum interrupt efficiency, a system program should not
; use more than the upper 3/4 of the stack."
ldx #$FF
txs ; Init stack pointer
txs ; Init stack pointer
; Switch in LC bank 2 for W/O
bit $C081
bit $C081
; Switch in LC bank 2 for W/O
bit $C081
bit $C081
; Set source start address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
sta $9B
sty $9C
; Set source start address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
sta $9B
sty $9C
; Set source last address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
sta $96
sty $97
; Set source last address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
sta $96
sty $97
; Set destination last address
lda #<__LC_LAST__
ldy #>__LC_LAST__
sta $94
sty $95
; Set destination last address
lda #<__LC_LAST__
ldy #>__LC_LAST__
sta $94
sty $95
; Call into Applesoft Block Transfer Utility - which handles zero
; sized blocks well - to move content of the LC memory area
jsr $D396 ; BLTU + 3
; Call into Applesoft Block Transfer Utility - which handles zero
; sized blocks well - to move content of the LC memory area
jsr $D396 ; BLTU + 3
; Set source start address
lda #<__ZPSAVE_RUN__
ldy #>__ZPSAVE_RUN__
sta $9B
sty $9C
; Set source start address
lda #<__ZPSAVE_RUN__
ldy #>__ZPSAVE_RUN__
sta $9B
sty $9C
; Set source last address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
sta $96
sty $97
; Set source last address
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
sta $96
sty $97
; Set destination last address
lda #<(__INIT_RUN__ + __INIT_SIZE__)
ldy #>(__INIT_RUN__ + __INIT_SIZE__)
sta $94
sty $95
; Set destination last address
lda #<(__INIT_RUN__ + __INIT_SIZE__)
ldy #>(__INIT_RUN__ + __INIT_SIZE__)
sta $94
sty $95
; Call into Applesoft Block Transfer Utility - which handles moving
; overlapping blocks upwards well - to move the INIT segment
jsr $D396 ; BLTU + 3
; Call into Applesoft Block Transfer Utility - which handles moving
; overlapping blocks upwards well - to move the INIT segment
jsr $D396 ; BLTU + 3
; Delegate all further processing to keep the STARTUP segment small
jsr init
@ -81,24 +78,14 @@
; Avoid re-entrance of donelib. This is also the _exit entry
_exit: ldx #<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
bit $C082
bit $C082
; Call module destructors
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
exit: ldx #$02
: lda rvsave,x
@ -122,8 +109,6 @@ exit: ldx #$02
; We're done
jmp (done)
; ------------------------------------------------------------------------
.segment "INIT"
; Save the zero page locations we need
@ -148,11 +133,11 @@ init: ldx #zpspace-1
; address of a routine that ... closes the files."
ldx #<_exit
lda #>_exit
jsr reset ; Setup RESET vector
jsr reset ; Setup RESET vector
; Check for ProDOS
ldy $BF00 ; MLI call entry point
cpy #$4C ; Is MLI present? (JMP opcode)
ldy $BF00 ; MLI call entry point
cpy #$4C ; Is MLI present? (JMP opcode)
bne basic
; Check ProDOS system bit map
@ -179,80 +164,20 @@ basic: lda HIMEM
: sta sp
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)
; jump to SYS and BIN programs with interrupts disabled
cli
; Enable interrupts as old ProDOS versions (i.e. 1.1.1)
; jump to SYS and BIN programs with interrupts disabled
cli
; Call module constructors
: jsr initlib
jsr initlib
; Switch in LC bank 2 for R/O
bit $C080
; Switch in LC bank 2 for R/O
bit $C080
; Push arguments and call main()
jmp callmain
; Print error message and return
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
.code
; Setup RESET vector
reset: stx SOFTEV
@ -266,37 +191,24 @@ quit: jsr $BF00 ; MLI call entry point
.byte $65 ; Quit
.word q_param
; ------------------------------------------------------------------------
.rodata
; MLI parameter list for quit
q_param:.byte $04 ; param_count
.byte $00 ; quit_type
.word $0000 ; reserved
.byte $00 ; reserved
.word $0000 ; reserved
; ------------------------------------------------------------------------
; MLI parameter list for quit
q_param:.byte $04 ; param_count
.byte $00 ; quit_type
.word $0000 ; reserved
.byte $00 ; reserved
.word $0000 ; reserved
.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
done: .addr DOSWARM
; ------------------------------------------------------------------------
.segment "ZPSAVE"
zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss
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);
;
.constructor initreboot
.export _rebootafterexit
.constructor initreboot, 11
.export _rebootafterexit
.import done, return
_rebootafterexit := return

View file

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

View file

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

View file

@ -12,8 +12,7 @@
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import callmain, zerobss, callirq
.import __INTERRUPTOR_COUNT__
.import callmain, zerobss
.import __STARTUP_LOAD__, __ZPSAVE_LOAD__
.import __RESERVED_MEMORY__
@ -23,7 +22,8 @@
; ------------------------------------------------------------------------
; EXE header
.segment "EXEHDR"
.segment "EXEHDR"
.word $FFFF
.word __STARTUP_LOAD__
.word __ZPSAVE_LOAD__ - 1
@ -31,7 +31,7 @@
; ------------------------------------------------------------------------
; Actual code
.segment "STARTUP"
.segment "STARTUP"
rts ; fix for SpartaDOS / OS/A+
; they first call the entry point from AUTOSTRT and
@ -74,22 +74,9 @@ L1: lda sp,x
sta APPMHI+1
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
NoIRQ1: jsr initlib
jsr initlib
; Set left margin to 0
@ -117,19 +104,9 @@ NoIRQ1: jsr initlib
_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
NoIRQ2: ldx spsave
ldx spsave
txs ; Restore stack pointer
; Restore left margin
@ -166,28 +143,17 @@ L2: lda zpsave,x
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
; ------------------------------------------------------------------------
.segment "ZPSAVE"
zpsave: .res zpspace
.bss
; ------------------------------------------------------------------------
.bss
spsave: .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 \
gotoxy.o \
gotoy.o \
irq.o \
joy_stat_stddrv.o \
joy_stddrv.o \
kbhit.o \

View file

@ -7,15 +7,13 @@
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import callmain, zerobss, callirq
.import __INTERRUPTOR_COUNT__
.import callmain, zerobss
.import __RAM_START__, __RAM_SIZE__
.import __ZPSAVE_LOAD__, __STACKSIZE__
.include "zeropage.inc"
.include "atmos.inc"
; ------------------------------------------------------------------------
; Oric tape header
@ -70,24 +68,9 @@ L1: lda sp,x
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
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
NoIRQ1: jsr initlib
jsr initlib
; Push arguments and call main()
@ -97,21 +80,9 @@ NoIRQ1: jsr initlib
_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
NoIRQ2: ldx spsave
ldx spsave
txs
lda stsave
sta STATUS
@ -129,34 +100,13 @@ L2: lda zpsave,x
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"
zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss
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 \
fast.o \
get_tv.o \
irq.o \
joy_stat_stddrv.o \
joy_stddrv.o \
kbhit.o \

View file

@ -2,124 +2,92 @@
; Startup code for cc65 (C128 version)
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import callirq, initlib, donelib
.import zerobss
.import push0, callmain
.import RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__, __STACKSIZE__
.importzp ST
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import zerobss
.import push0, callmain
.import RESTOR, BSOUT, CLRCH
.import __RAM_START__, __RAM_SIZE__, __STACKSIZE__
.importzp ST
.include "zeropage.inc"
.include "c128.inc"
.include "zeropage.inc"
.include "c128.inc"
; ------------------------------------------------------------------------
; Constants
IRQInd = $2FD ; JMP $0000 - used as indirect IRQ vector
; ------------------------------------------------------------------------
; Startup code
.segment "STARTUP"
.segment "STARTUP"
Start:
; Switch to the second charset
lda #14
jsr BSOUT
lda #14
jsr BSOUT
; Before doing anything else, we have to setup our banking configuration.
; Otherwise just the lowest 16K are actually RAM. Writing through the ROM
; to the underlying RAM works, but it is bad style.
lda MMU_CR ; Get current memory configuration...
pha ; ...and save it for later
lda #MMU_CFG_CC65 ; Bank0 with kernal ROM
sta MMU_CR
lda MMU_CR ; Get current memory configuration...
pha ; ...and save it for later
lda #MMU_CFG_CC65 ; Bank0 with kernal ROM
sta MMU_CR
; Save the zero page locations we need
ldx #zpspace-1
L1: lda sp,x
sta zpsave,x
dex
bpl L1
ldx #zpspace-1
L1: lda sp,x
sta zpsave,x
dex
bpl L1
; Clear the BSS data
jsr zerobss
jsr zerobss
; Save system stuff and setup the stack
pla ; Get MMU setting
sta mmusave
pla ; Get MMU setting
sta mmusave
tsx
stx spsave ; Save the system stack pointer
tsx
stx spsave ; Save the system stack pointer
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
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
sta sp+1 ; Set argument stack ptr
; Call module constructors
NoIRQ1: jsr initlib
jsr initlib
; 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
; original value of this register.
lda #0
sta FNAM_BANK
lda #0
sta FNAM_BANK
; Push arguments and call main()
jsr callmain
jsr callmain
; Back from main (this is also the _exit entry). Run module destructors
_exit: 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
_exit: pha ; Save the return code on stack
jsr donelib
; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1
ldx #zpspace-1
L2: lda zpsave,x
sta sp,x
dex
bpl L2
sta sp,x
dex
bpl L2
; Place the program return code into ST
@ -128,49 +96,25 @@ L2: lda zpsave,x
; Reset the stack and the memory configuration
ldx spsave
txs
ldx mmusave
ldx spsave
txs
ldx mmusave
stx MMU_CR
; Done, return to BASIC
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
rts
; ------------------------------------------------------------------------
; Data
.segment "ZPSAVE"
.segment "ZPSAVE"
zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss
spsave: .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 \
devnum.o \
get_tv.o \
irq.o \
joy_stat_stddrv.o \
joy_stddrv.o \
kbhit.o \

View file

@ -6,31 +6,29 @@
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq
.import callmain, zerobss
.import MEMTOP, RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.importzp ST
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import callmain, zerobss
.import MEMTOP, RESTOR, BSOUT, CLRCH
.importzp ST
.include "zeropage.inc"
.include "zeropage.inc"
.include "plus4.inc"
; ------------------------------------------------------------------------
; Startup code
.segment "STARTUP"
.segment "STARTUP"
Start:
; Save the zero page locations we need
ldx #zpspace-1
ldx #zpspace-1
L1: lda sp,x
sta zpsave,x
dex
bpl L1
sta zpsave,x
dex
bpl L1
; Switch to second charset
@ -43,65 +41,38 @@ L1: lda sp,x
; Save system stuff and setup the stack
tsx
stx spsave ; save system stk ptr
tsx
stx spsave ; save system stk ptr
sec
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
ldy #$80
ldx #$00
MemOk: stx sp
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
sty sp+1 ; set argument stack ptr
; Call module constructors
NoIRQ1: jsr initlib
jsr initlib
; Push arguments and call main()
jsr callmain
jsr callmain
; Call module destructors. This is also the _exit entry.
_exit: pha ; Save the return code on stack
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
NoIRQ2: ldx #zpspace-1
ldx #zpspace-1
L2: lda zpsave,x
sta sp,x
dex
bpl L2
bpl L2
; Store the return code into ST
@ -118,26 +89,13 @@ L2: lda zpsave,x
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
; ------------------------------------------------------------------------
.bss
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 \
get_ostype.o \
get_tv.o \
irq.o \
joy_stat_stddrv.o \
joy_stddrv.o \
kbhit.o \

View file

@ -3,34 +3,33 @@
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq
.import zerobss
.import callmain
.import RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import zerobss
.import callmain
.import RESTOR, BSOUT, CLRCH
.import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import __STACKSIZE__ ; Linker generated
.importzp ST
.importzp ST
.include "zeropage.inc"
.include "c64.inc"
.include "zeropage.inc"
.include "c64.inc"
; ------------------------------------------------------------------------
; Startup code
.segment "STARTUP"
.segment "STARTUP"
Start:
; Save the zero page locations we need
ldx #zpspace-1
ldx #zpspace-1
L1: lda sp,x
sta zpsave,x
sta zpsave,x
dex
bpl L1
bpl L1
; Switch to second charset
@ -40,9 +39,9 @@ L1: lda sp,x
; Switch off the BASIC ROM
lda $01
pha ; Remember the value
pha ; Remember the value
and #$F8
ora #$06 ; Enable kernal+I/O, disable basic
ora #$06 ; Enable kernal+I/O, disable basic
sta $01
; Clear the BSS data
@ -51,64 +50,37 @@ L1: lda sp,x
; Save system settings and setup the stack
pla
sta mmusave ; Save the memory configuration
pla
sta mmusave ; Save the memory configuration
tsx
stx spsave ; Save the system stack ptr
tsx
stx spsave ; Save the system stack ptr
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
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
sta sp+1 ; Set argument stack ptr
; Call module constructors
NoIRQ1: jsr initlib
jsr initlib
; Push arguments and call main
jsr callmain
jsr callmain
; Back from main (This is also the _exit entry). Run module destructors
_exit: 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
_exit: pha ; Save the return code on stack
jsr donelib
; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1
L2: lda zpsave,x
sta sp,x
dex
bpl L2
ldx #zpspace-1
L2: lda zpsave,x
sta sp,x
dex
bpl L2
; Place the program return code into ST
@ -117,31 +89,19 @@ L2: lda zpsave,x
; Restore system stuff
ldx spsave
txs ; Restore stack pointer
ldx mmusave
stx $01 ; Restore memory configuration
ldx spsave
txs ; Restore stack pointer
ldx mmusave
stx $01 ; Restore memory configuration
; Back to basic
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
rts
; ------------------------------------------------------------------------
; Data
.data
IRQInd: jmp $0000
.segment "ZPSAVE"
.segment "ZPSAVE"
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 \
devnum.o \
extzp.o \
irq.o \
joy_stat_stddrv.o \
joy_stddrv.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 \
extzp.o \
get_tv.o \
irq.o \
kbhit.o \
kclose.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 \
exehdr.o \
extzp.o \
irq.o \
joy_stat_stddrv.o \
joy_stddrv.o \
kbhit.o \

View file

@ -15,31 +15,29 @@
; on the front of the fully linked binary (see EXEHDR segment.)
;
.include "lynx.inc"
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import callirq, initlib, donelib
.import zerobss
.import callmain
.import _main
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__, __STACKSIZE__
.import initlib, donelib
.import zerobss
.import callmain
.import _main
.import __RAM_START__, __RAM_SIZE__, __STACKSIZE__
.include "zeropage.inc"
.include "extzp.inc"
.include "zeropage.inc"
.include "extzp.inc"
.include "lynx.inc"
; ------------------------------------------------------------------------
; Mikey and Suzy init data, reg offsets and data
.rodata
SuzyInitReg: .byte $28,$2a,$04,$06,$92,$83,$90
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
SuzyInitReg: .byte $28,$2a,$04,$06,$92,$83,$90
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
; ------------------------------------------------------------------------
; Actual code
@ -50,116 +48,89 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2
sei
cld
ldx #$FF
ldx #$FF
txs
; init bank switching
lda #$C
sta MAPCTL ; $FFF9
lda #$C
sta MAPCTL ; $FFF9
; disable all timer interrupts
lda #$80
trb TIM0CTLA
trb TIM1CTLA
trb TIM2CTLA
trb TIM3CTLA
trb TIM5CTLA
trb TIM6CTLA
trb TIM7CTLA
lda #$80
trb TIM0CTLA
trb TIM1CTLA
trb TIM2CTLA
trb TIM3CTLA
trb TIM5CTLA
trb TIM6CTLA
trb TIM7CTLA
; disable TX/RX IRQ, set to 8E1
lda #%11101
sta SERCTL
lda #%11101
sta SERCTL
; clear all pending interrupts
lda INTSET
sta INTRST
lda INTSET
sta INTRST
; setup the stack
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1
; Init Mickey
ldx #.sizeof(MikeyInitReg)-1
mloop: ldy MikeyInitReg,x
lda MikeyInitData,x
sta $fd00,y
ldx #.sizeof(MikeyInitReg)-1
mloop: ldy MikeyInitReg,x
lda MikeyInitData,x
sta $fd00,y
dex
bpl mloop
bpl mloop
; these are RAM-shadows of read only regs
ldx #$1b
stx __iodat
dex ; $1A
stx __iodir
ldx #$d
stx __viddma
ldx #$1b
stx __iodat
dex ; $1A
stx __iodir
ldx #$d
stx __viddma
; Init Suzy
ldx #.sizeof(SuzyInitReg)-1
sloop: ldy SuzyInitReg,x
lda SuzyInitData,x
sta $fc00,y
ldx #.sizeof(SuzyInitReg)-1
sloop: ldy SuzyInitReg,x
lda SuzyInitData,x
sta $fc00,y
dex
bpl sloop
bpl sloop
lda #$24
sta __sprsys
lda #$24
sta __sprsys
cli
; Clear the BSS data
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
jsr zerobss
; Call module constructors
NoIRQ1: jsr initlib
jsr initlib
; Push arguments and call main
jsr callmain
jsr callmain
; Call module destructors. This is also the _exit entry.
_exit: jsr donelib ; Run module destructors
_exit: jsr donelib ; Run module destructors
; Endless loop
noret: bra noret
.segment "CODE"
IRQStub:
phy
phx
pha
cld
jsr callirq
lda INTSET
sta INTRST
pla
plx
ply
rti
noret: bra noret

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 \
devnum.o \
get_tv.o \
irq.o \
joy_stat_stddrv.o \
joy_stddrv.o \
kbhit.o \

View file

@ -2,33 +2,32 @@
; Startup code for cc65 (PET version)
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq
.import zerobss, push0
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import zerobss, push0
.import callmain
.import CLRCH, BSOUT
.import __INTERRUPTOR_COUNT__
.importzp ST
.import CLRCH, BSOUT
.importzp ST
.include "zeropage.inc"
.include "zeropage.inc"
.include "pet.inc"
.include "../cbm/cbm.inc"
; ------------------------------------------------------------------------
; Startup code
.segment "STARTUP"
.segment "STARTUP"
Start:
; Save the zero page locations we need
ldx #zpspace-1
ldx #zpspace-1
L1: lda sp,x
sta zpsave,x
sta zpsave,x
dex
bpl L1
bpl L1
; 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
@ -36,13 +35,13 @@ L1: lda sp,x
; information, we need to save and restore it here.
; Thanks to Stefan Haubenthal for this information!
lda FNLEN
pha ; Save FNLEN
lda FNLEN
pha ; Save FNLEN
lda #14
; sta $E84C ; See PET FAQ
jsr BSOUT
pla
sta FNLEN ; Restore FNLEN
pla
sta FNLEN ; Restore FNLEN
; Clear the BSS data
@ -50,60 +49,34 @@ L1: lda sp,x
; Save system stuff and setup the stack
tsx
stx spsave ; Save the system stack ptr
tsx
stx spsave ; Save the system stack ptr
lda MEMSIZE
lda MEMSIZE
sta sp
lda MEMSIZE+1
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
sta sp+1 ; Set argument stack ptr
; Call module constructors
NoIRQ1: jsr initlib
jsr initlib
; Push arguments and call main()
jsr callmain
jsr callmain
; Call module destructors. This is also the _exit entry.
_exit: pha ; Save the return code on stack
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
_exit: pha ; Save the return code on stack
jsr donelib
; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1
ldx #zpspace-1
L2: lda zpsave,x
sta sp,x
dex
bpl L2
bpl L2
; Store the program return code into ST
@ -113,33 +86,21 @@ L2: lda zpsave,x
; Restore the stack pointer
ldx spsave
txs ; Restore stack pointer
txs ; Restore stack pointer
; 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
IRQInd: jmp $0000
.segment "ZPSAVE"
.segment "ZPSAVE"
zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss
spsave: .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 \
devnum.o \
get_tv.o \
irq.o \
joy_stat_stddrv.o \
joy_stddrv.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.
;
.export callirq
.export callirq_y ; Same but with Y preloaded
.export __CALLIRQ__: absolute = 1
.import __INTERRUPTOR_TABLE__, __INTERRUPTOR_COUNT__
.export callirq
.export callirq_y ; Same but with Y preloaded
.export __CALLIRQ__ : absolute = 1
.constructor irq_init, 10
.destructor irq_done, 10
.code
.import __INTERRUPTOR_TABLE__, __INTERRUPTOR_COUNT__
.import initirq
.import doneirq
irq_init := initirq
irq_done := doneirq
; --------------------------------------------------------------------------
; Call all IRQ routines. The function needs to use self modifying code and
@ -51,14 +56,12 @@ callirq_y:
loop: dey
lda __INTERRUPTOR_TABLE__,y
sta jmpvec+2 ; Modify code below
dey
dey
lda __INTERRUPTOR_TABLE__,y
sta jmpvec+1 ; Modify code below
sty index+1 ; Modify code below
jmpvec: jsr $FFFF ; Patched at runtime
sty index+1 ; Modify code below
jmpvec: jsr $FFFF ; Patched at runtime
bcs done ; Bail out if interrupt handled
index: ldy #$FF ; Patched at runtime
bne loop
index: ldy #$FF ; Patched at runtime
bne loop
done: rts

View file

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

View file

@ -3,33 +3,32 @@
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq
.import zerobss, push0
.import callmain
.import RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import __STACKSIZE__ ; Linker generated
.importzp ST
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import zerobss, push0
.import callmain
.import RESTOR, BSOUT, CLRCH
.import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import __STACKSIZE__ ; Linker generated
.importzp ST
.include "zeropage.inc"
.include "vic20.inc"
.include "zeropage.inc"
.include "vic20.inc"
; ------------------------------------------------------------------------
; Startup code
.segment "STARTUP"
.segment "STARTUP"
Start:
; Save the zero page locations we need
ldx #zpspace-1
ldx #zpspace-1
L1: lda sp,x
sta zpsave,x
sta zpsave,x
dex
bpl L1
bpl L1
; Switch to second charset
@ -42,60 +41,34 @@ L1: lda sp,x
; Save system stuff and setup the stack
tsx
stx spsave ; Save the system stack ptr
tsx
stx spsave ; Save the system stack ptr
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
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
sta sp+1 ; Set argument stack ptr
; Call module constructors
NoIRQ1: jsr initlib
jsr initlib
; Push arguments and call main()
jsr callmain
jsr callmain
; Back from main (This is also the _exit entry). Run module destructors
_exit: 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
_exit: pha ; Save the return code on stack
jsr donelib
; Copy back the zero page stuff
NoIRQ2: ldx #zpspace-1
ldx #zpspace-1
L2: lda zpsave,x
sta sp,x
dex
bpl L2
bpl L2
; Place the program return code into ST
@ -104,33 +77,21 @@ L2: lda zpsave,x
; Restore the stack pointer
ldx spsave
ldx spsave
txs
; 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
IRQInd: jmp $0000
.segment "ZPSAVE"
.segment "ZPSAVE"
zpsave: .res zpspace
; ------------------------------------------------------------------------
.bss
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