mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
irq handler saves zeropage scratch registers, fixes #8
This commit is contained in:
parent
1e045b6a62
commit
f3fc2fe523
@ -288,7 +288,9 @@ asmsub set_irqvec_excl() -> clobbers(A) -> () {
|
||||
sta c64.CINV+1
|
||||
cli
|
||||
rts
|
||||
_irq_handler jsr irq.irq
|
||||
_irq_handler jsr set_irqvec._irq_handler_init
|
||||
jsr irq.irq
|
||||
jsr set_irqvec._irq_handler_end
|
||||
lda #$ff
|
||||
sta c64.VICIRQ ; acknowledge raster irq
|
||||
lda c64.CIA1ICR ; acknowledge CIA1 interrupt
|
||||
@ -305,10 +307,64 @@ asmsub set_irqvec() -> clobbers(A) -> () {
|
||||
sta c64.CINV+1
|
||||
cli
|
||||
rts
|
||||
_irq_handler jsr irq.irq
|
||||
_irq_handler jsr _irq_handler_init
|
||||
jsr irq.irq
|
||||
jsr _irq_handler_end
|
||||
jmp c64.IRQDFRT ; continue with normal kernel irq routine
|
||||
|
||||
}}
|
||||
_irq_handler_init
|
||||
; save all zp scratch registers and the X register as these might be clobbered by the irq routine
|
||||
stx IRQ_X_REG
|
||||
lda c64.SCRATCH_ZPB1
|
||||
sta IRQ_SCRATCH_ZPB1
|
||||
lda c64.SCRATCH_ZPREG
|
||||
sta IRQ_SCRATCH_ZPREG
|
||||
lda c64.SCRATCH_ZPREGX
|
||||
sta IRQ_SCRATCH_ZPREGX
|
||||
lda c64.SCRATCH_ZPWORD1
|
||||
sta IRQ_SCRATCH_ZPWORD1
|
||||
lda c64.SCRATCH_ZPWORD1+1
|
||||
sta IRQ_SCRATCH_ZPWORD1+1
|
||||
lda c64.SCRATCH_ZPWORD2
|
||||
sta IRQ_SCRATCH_ZPWORD2
|
||||
lda c64.SCRATCH_ZPWORD2+1
|
||||
sta IRQ_SCRATCH_ZPWORD2+1
|
||||
; stack protector; make sure we don't clobber the top of the evaluation stack
|
||||
dex
|
||||
dex
|
||||
dex
|
||||
dex
|
||||
dex
|
||||
dex
|
||||
rts
|
||||
|
||||
_irq_handler_end
|
||||
; restore all zp scratch registers and the X register
|
||||
lda IRQ_SCRATCH_ZPB1
|
||||
sta c64.SCRATCH_ZPB1
|
||||
lda IRQ_SCRATCH_ZPREG
|
||||
sta c64.SCRATCH_ZPREG
|
||||
lda IRQ_SCRATCH_ZPREGX
|
||||
sta c64.SCRATCH_ZPREGX
|
||||
lda IRQ_SCRATCH_ZPWORD1
|
||||
sta c64.SCRATCH_ZPWORD1
|
||||
lda IRQ_SCRATCH_ZPWORD1+1
|
||||
sta c64.SCRATCH_ZPWORD1+1
|
||||
lda IRQ_SCRATCH_ZPWORD2
|
||||
sta c64.SCRATCH_ZPWORD2
|
||||
lda IRQ_SCRATCH_ZPWORD2+1
|
||||
sta c64.SCRATCH_ZPWORD2+1
|
||||
ldx IRQ_X_REG
|
||||
rts
|
||||
|
||||
IRQ_X_REG .byte 0
|
||||
IRQ_SCRATCH_ZPB1 .byte 0
|
||||
IRQ_SCRATCH_ZPREG .byte 0
|
||||
IRQ_SCRATCH_ZPREGX .byte 0
|
||||
IRQ_SCRATCH_ZPWORD1 .word 0
|
||||
IRQ_SCRATCH_ZPWORD2 .word 0
|
||||
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
@ -341,7 +397,9 @@ asmsub set_rasterirq(uword rasterpos @ AY) -> clobbers(A) -> () {
|
||||
rts
|
||||
|
||||
_raster_irq_handler
|
||||
jsr set_irqvec._irq_handler_init
|
||||
jsr irq.irq
|
||||
jsr set_irqvec._irq_handler_end
|
||||
lda #$ff
|
||||
sta c64.VICIRQ ; acknowledge raster irq
|
||||
jmp c64.IRQDFRT
|
||||
@ -380,7 +438,9 @@ asmsub set_rasterirq_excl(uword rasterpos @ AY) -> clobbers(A) -> () {
|
||||
rts
|
||||
|
||||
_raster_irq_handler
|
||||
jsr set_irqvec._irq_handler_init
|
||||
jsr irq.irq
|
||||
jsr set_irqvec._irq_handler_end
|
||||
lda #$ff
|
||||
sta c64.VICIRQ ; acknowledge raster irq
|
||||
jmp c64.IRQDFEND ; end irq processing - don't call kernel
|
||||
|
@ -227,7 +227,6 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
if (callstack.size > 128)
|
||||
throw VmExecutionException("too many nested/recursive calls")
|
||||
} catch (bp: VmBreakpointException) {
|
||||
currentInstructionPtr++ // TODO necessary still?
|
||||
println("breakpoint encountered, source line: $sourceLine")
|
||||
throw bp
|
||||
} catch (es: EmptyStackException) {
|
||||
@ -702,50 +701,50 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
Opcode.SHIFTEDL_BYTE, Opcode.SHL_BYTE -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UBYTE, DataType.BYTE)
|
||||
P_carry = (v.integerValue() and 0x80)!=0
|
||||
val value=v.shl()
|
||||
evalstack.push(value)
|
||||
setFlags(value)
|
||||
// TODO carry flag
|
||||
}
|
||||
Opcode.SHIFTEDL_WORD, Opcode.SHL_WORD -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UWORD, DataType.WORD)
|
||||
P_carry = (v.integerValue() and 0x8000)!=0
|
||||
val value=v.shl()
|
||||
evalstack.push(value)
|
||||
setFlags(value)
|
||||
// TODO carry flag
|
||||
}
|
||||
Opcode.SHIFTEDR_UBYTE, Opcode.SHR_UBYTE -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UBYTE)
|
||||
P_carry = (v.integerValue() and 0x01)!=0
|
||||
val value=v.shr()
|
||||
evalstack.push(value)
|
||||
setFlags(value)
|
||||
// TODO carry flag
|
||||
}
|
||||
Opcode.SHIFTEDR_SBYTE, Opcode.SHR_SBYTE -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.BYTE)
|
||||
P_carry = (v.integerValue() and 0x01)!=0
|
||||
val value=v.shr()
|
||||
evalstack.push(value)
|
||||
setFlags(value)
|
||||
// TODO carry flag
|
||||
}
|
||||
Opcode.SHIFTEDR_UWORD, Opcode.SHR_UWORD -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UWORD)
|
||||
P_carry = (v.integerValue() and 0x01)!=0
|
||||
val value=v.shr()
|
||||
evalstack.push(value)
|
||||
setFlags(value)
|
||||
// TODO carry flag
|
||||
}
|
||||
Opcode.SHIFTEDR_SWORD, Opcode.SHR_SWORD -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.WORD)
|
||||
P_carry = (v.integerValue() and 0x01)!=0
|
||||
val value=v.shr()
|
||||
evalstack.push(value)
|
||||
setFlags(value)
|
||||
// TODO carry flag
|
||||
}
|
||||
Opcode.ROL_BYTE -> {
|
||||
val v = evalstack.pop()
|
||||
|
@ -23,23 +23,19 @@
|
||||
ubyte ypos = 0
|
||||
|
||||
sub irq() {
|
||||
Y++ ; delay for alignment
|
||||
Y++ ; delay for alignment
|
||||
Y++ ; delay for alignment
|
||||
Y++ ; delay for alignment
|
||||
Y++ ; slight timing delay to avoid rasterline transition issues
|
||||
ubyte rasterpos = c64.RASTER
|
||||
|
||||
if color!=len(colors) {
|
||||
c64.EXTCOL = colors[color]
|
||||
c64.RASTER = rasterpos+barheight
|
||||
color++
|
||||
c64.RASTER = rasterpos+barheight
|
||||
}
|
||||
else {
|
||||
Y++ ; delay for alignment
|
||||
Y++ ; delay for alignment
|
||||
ypos += 2
|
||||
c64.EXTCOL = 0
|
||||
c64.RASTER = sin8u(ypos)/2+40
|
||||
color = 0
|
||||
c64.RASTER = sin8u(ypos)/2+40
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,33 @@
|
||||
%import c64utils
|
||||
%import c64lib
|
||||
%zeropage basicsafe
|
||||
|
||||
~ main {
|
||||
|
||||
; @todo see problem in looplabelproblem.p8
|
||||
|
||||
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
ubyte ub1
|
||||
ubyte ub2
|
||||
ubyte ub3
|
||||
ubyte ub4
|
||||
ubyte ub5
|
||||
c64utils.set_rasterirq(220) ; enable animation
|
||||
|
||||
ub1, ub2 = test2()
|
||||
c64scr.print_ub(ub1)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(ub2)
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
ub1, ub2 = test3()
|
||||
c64scr.print_ub(ub1)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(ub2)
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
uword offs=0
|
||||
while(true) {
|
||||
uword z=1
|
||||
for ubyte x in 0 to 200 {
|
||||
@(z*($0400+offs)) = lsb(offs+x)
|
||||
offs += 1
|
||||
if offs > 40*25
|
||||
offs=0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asmsub test2() -> clobbers() -> (ubyte @Pc, ubyte @A) {
|
||||
%asm {{
|
||||
lda #100
|
||||
ldy #100
|
||||
sec
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub test3() -> clobbers() -> (ubyte @Pc, ubyte @A) {
|
||||
%asm {{
|
||||
lda #101
|
||||
ldy #101
|
||||
clc
|
||||
rts
|
||||
}}
|
||||
~ irq {
|
||||
|
||||
sub irq() {
|
||||
c64.EXTCOL = X
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user