mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +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
|
sta c64.CINV+1
|
||||||
cli
|
cli
|
||||||
rts
|
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
|
lda #$ff
|
||||||
sta c64.VICIRQ ; acknowledge raster irq
|
sta c64.VICIRQ ; acknowledge raster irq
|
||||||
lda c64.CIA1ICR ; acknowledge CIA1 interrupt
|
lda c64.CIA1ICR ; acknowledge CIA1 interrupt
|
||||||
@ -305,9 +307,63 @@ asmsub set_irqvec() -> clobbers(A) -> () {
|
|||||||
sta c64.CINV+1
|
sta c64.CINV+1
|
||||||
cli
|
cli
|
||||||
rts
|
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
|
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
|
rts
|
||||||
|
|
||||||
_raster_irq_handler
|
_raster_irq_handler
|
||||||
|
jsr set_irqvec._irq_handler_init
|
||||||
jsr irq.irq
|
jsr irq.irq
|
||||||
|
jsr set_irqvec._irq_handler_end
|
||||||
lda #$ff
|
lda #$ff
|
||||||
sta c64.VICIRQ ; acknowledge raster irq
|
sta c64.VICIRQ ; acknowledge raster irq
|
||||||
jmp c64.IRQDFRT
|
jmp c64.IRQDFRT
|
||||||
@ -380,7 +438,9 @@ asmsub set_rasterirq_excl(uword rasterpos @ AY) -> clobbers(A) -> () {
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
_raster_irq_handler
|
_raster_irq_handler
|
||||||
|
jsr set_irqvec._irq_handler_init
|
||||||
jsr irq.irq
|
jsr irq.irq
|
||||||
|
jsr set_irqvec._irq_handler_end
|
||||||
lda #$ff
|
lda #$ff
|
||||||
sta c64.VICIRQ ; acknowledge raster irq
|
sta c64.VICIRQ ; acknowledge raster irq
|
||||||
jmp c64.IRQDFEND ; end irq processing - don't call kernel
|
jmp c64.IRQDFEND ; end irq processing - don't call kernel
|
||||||
|
@ -227,7 +227,6 @@ class StackVm(private var traceOutputFile: String?) {
|
|||||||
if (callstack.size > 128)
|
if (callstack.size > 128)
|
||||||
throw VmExecutionException("too many nested/recursive calls")
|
throw VmExecutionException("too many nested/recursive calls")
|
||||||
} catch (bp: VmBreakpointException) {
|
} catch (bp: VmBreakpointException) {
|
||||||
currentInstructionPtr++ // TODO necessary still?
|
|
||||||
println("breakpoint encountered, source line: $sourceLine")
|
println("breakpoint encountered, source line: $sourceLine")
|
||||||
throw bp
|
throw bp
|
||||||
} catch (es: EmptyStackException) {
|
} catch (es: EmptyStackException) {
|
||||||
@ -702,50 +701,50 @@ class StackVm(private var traceOutputFile: String?) {
|
|||||||
Opcode.SHIFTEDL_BYTE, Opcode.SHL_BYTE -> {
|
Opcode.SHIFTEDL_BYTE, Opcode.SHL_BYTE -> {
|
||||||
val v = evalstack.pop()
|
val v = evalstack.pop()
|
||||||
checkDt(v, DataType.UBYTE, DataType.BYTE)
|
checkDt(v, DataType.UBYTE, DataType.BYTE)
|
||||||
|
P_carry = (v.integerValue() and 0x80)!=0
|
||||||
val value=v.shl()
|
val value=v.shl()
|
||||||
evalstack.push(value)
|
evalstack.push(value)
|
||||||
setFlags(value)
|
setFlags(value)
|
||||||
// TODO carry flag
|
|
||||||
}
|
}
|
||||||
Opcode.SHIFTEDL_WORD, Opcode.SHL_WORD -> {
|
Opcode.SHIFTEDL_WORD, Opcode.SHL_WORD -> {
|
||||||
val v = evalstack.pop()
|
val v = evalstack.pop()
|
||||||
checkDt(v, DataType.UWORD, DataType.WORD)
|
checkDt(v, DataType.UWORD, DataType.WORD)
|
||||||
|
P_carry = (v.integerValue() and 0x8000)!=0
|
||||||
val value=v.shl()
|
val value=v.shl()
|
||||||
evalstack.push(value)
|
evalstack.push(value)
|
||||||
setFlags(value)
|
setFlags(value)
|
||||||
// TODO carry flag
|
|
||||||
}
|
}
|
||||||
Opcode.SHIFTEDR_UBYTE, Opcode.SHR_UBYTE -> {
|
Opcode.SHIFTEDR_UBYTE, Opcode.SHR_UBYTE -> {
|
||||||
val v = evalstack.pop()
|
val v = evalstack.pop()
|
||||||
checkDt(v, DataType.UBYTE)
|
checkDt(v, DataType.UBYTE)
|
||||||
|
P_carry = (v.integerValue() and 0x01)!=0
|
||||||
val value=v.shr()
|
val value=v.shr()
|
||||||
evalstack.push(value)
|
evalstack.push(value)
|
||||||
setFlags(value)
|
setFlags(value)
|
||||||
// TODO carry flag
|
|
||||||
}
|
}
|
||||||
Opcode.SHIFTEDR_SBYTE, Opcode.SHR_SBYTE -> {
|
Opcode.SHIFTEDR_SBYTE, Opcode.SHR_SBYTE -> {
|
||||||
val v = evalstack.pop()
|
val v = evalstack.pop()
|
||||||
checkDt(v, DataType.BYTE)
|
checkDt(v, DataType.BYTE)
|
||||||
|
P_carry = (v.integerValue() and 0x01)!=0
|
||||||
val value=v.shr()
|
val value=v.shr()
|
||||||
evalstack.push(value)
|
evalstack.push(value)
|
||||||
setFlags(value)
|
setFlags(value)
|
||||||
// TODO carry flag
|
|
||||||
}
|
}
|
||||||
Opcode.SHIFTEDR_UWORD, Opcode.SHR_UWORD -> {
|
Opcode.SHIFTEDR_UWORD, Opcode.SHR_UWORD -> {
|
||||||
val v = evalstack.pop()
|
val v = evalstack.pop()
|
||||||
checkDt(v, DataType.UWORD)
|
checkDt(v, DataType.UWORD)
|
||||||
|
P_carry = (v.integerValue() and 0x01)!=0
|
||||||
val value=v.shr()
|
val value=v.shr()
|
||||||
evalstack.push(value)
|
evalstack.push(value)
|
||||||
setFlags(value)
|
setFlags(value)
|
||||||
// TODO carry flag
|
|
||||||
}
|
}
|
||||||
Opcode.SHIFTEDR_SWORD, Opcode.SHR_SWORD -> {
|
Opcode.SHIFTEDR_SWORD, Opcode.SHR_SWORD -> {
|
||||||
val v = evalstack.pop()
|
val v = evalstack.pop()
|
||||||
checkDt(v, DataType.WORD)
|
checkDt(v, DataType.WORD)
|
||||||
|
P_carry = (v.integerValue() and 0x01)!=0
|
||||||
val value=v.shr()
|
val value=v.shr()
|
||||||
evalstack.push(value)
|
evalstack.push(value)
|
||||||
setFlags(value)
|
setFlags(value)
|
||||||
// TODO carry flag
|
|
||||||
}
|
}
|
||||||
Opcode.ROL_BYTE -> {
|
Opcode.ROL_BYTE -> {
|
||||||
val v = evalstack.pop()
|
val v = evalstack.pop()
|
||||||
|
@ -23,23 +23,19 @@
|
|||||||
ubyte ypos = 0
|
ubyte ypos = 0
|
||||||
|
|
||||||
sub irq() {
|
sub irq() {
|
||||||
Y++ ; delay for alignment
|
Y++ ; slight timing delay to avoid rasterline transition issues
|
||||||
Y++ ; delay for alignment
|
|
||||||
Y++ ; delay for alignment
|
|
||||||
Y++ ; delay for alignment
|
|
||||||
ubyte rasterpos = c64.RASTER
|
ubyte rasterpos = c64.RASTER
|
||||||
|
|
||||||
if color!=len(colors) {
|
if color!=len(colors) {
|
||||||
c64.EXTCOL = colors[color]
|
c64.EXTCOL = colors[color]
|
||||||
c64.RASTER = rasterpos+barheight
|
|
||||||
color++
|
color++
|
||||||
|
c64.RASTER = rasterpos+barheight
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Y++ ; delay for alignment
|
|
||||||
Y++ ; delay for alignment
|
|
||||||
ypos += 2
|
ypos += 2
|
||||||
c64.EXTCOL = 0
|
c64.EXTCOL = 0
|
||||||
c64.RASTER = sin8u(ypos)/2+40
|
|
||||||
color = 0
|
color = 0
|
||||||
|
c64.RASTER = sin8u(ypos)/2+40
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,33 @@
|
|||||||
%import c64utils
|
%import c64utils
|
||||||
|
%import c64lib
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
~ main {
|
|
||||||
|
|
||||||
; @todo see problem in looplabelproblem.p8
|
; @todo see problem in looplabelproblem.p8
|
||||||
|
|
||||||
|
|
||||||
|
~ main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte ub1
|
c64utils.set_rasterirq(220) ; enable animation
|
||||||
ubyte ub2
|
|
||||||
ubyte ub3
|
|
||||||
ubyte ub4
|
|
||||||
ubyte ub5
|
|
||||||
|
|
||||||
ub1, ub2 = test2()
|
uword offs=0
|
||||||
c64scr.print_ub(ub1)
|
while(true) {
|
||||||
c64.CHROUT('\n')
|
uword z=1
|
||||||
c64scr.print_ub(ub2)
|
for ubyte x in 0 to 200 {
|
||||||
c64.CHROUT('\n')
|
@(z*($0400+offs)) = lsb(offs+x)
|
||||||
c64.CHROUT('\n')
|
offs += 1
|
||||||
ub1, ub2 = test3()
|
if offs > 40*25
|
||||||
c64scr.print_ub(ub1)
|
offs=0
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64scr.print_ub(ub2)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub test2() -> clobbers() -> (ubyte @Pc, ubyte @A) {
|
|
||||||
%asm {{
|
|
||||||
lda #100
|
|
||||||
ldy #100
|
|
||||||
sec
|
|
||||||
rts
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
asmsub test3() -> clobbers() -> (ubyte @Pc, ubyte @A) {
|
|
||||||
%asm {{
|
~ irq {
|
||||||
lda #101
|
|
||||||
ldy #101
|
sub irq() {
|
||||||
clc
|
c64.EXTCOL = X
|
||||||
rts
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user