mirror of
https://github.com/irmen/prog8.git
synced 2024-06-26 07:29:32 +00:00
65C02 cpu: use TRB and TSB instructions for in-place AND/OR.
This commit is contained in:
parent
11b7c4459e
commit
82a15b5a16
|
@ -1192,8 +1192,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||
}
|
||||
}
|
||||
}
|
||||
"&" -> asmgen.out(" lda $name | and #$value | sta $name")
|
||||
"|" -> asmgen.out(" lda $name | ora #$value | sta $name")
|
||||
"&" -> immediateAndInplace(name, value)
|
||||
"|" -> immediateOrInplace(name, value)
|
||||
"^" -> asmgen.out(" lda $name | eor #$value | sta $name")
|
||||
"==" -> {
|
||||
asmgen.out("""
|
||||
|
@ -1314,6 +1314,22 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||
}
|
||||
}
|
||||
|
||||
private fun immediateAndInplace(name: String, value: Int) {
|
||||
if(asmgen.isTargetCpu(CpuType.CPU65c02)) {
|
||||
asmgen.out(" lda #${value xor 255} | trb $name") // reset bit
|
||||
} else {
|
||||
asmgen.out(" lda $name | and #$value | sta $name")
|
||||
}
|
||||
}
|
||||
|
||||
private fun immediateOrInplace(name: String, value: Int) {
|
||||
if(asmgen.isTargetCpu(CpuType.CPU65c02) && ((value and (value-1))==0)) {
|
||||
asmgen.out(" lda #$value | tsb $name") // set bit
|
||||
} else {
|
||||
asmgen.out(" lda $name | ora #$value | sta $name")
|
||||
}
|
||||
}
|
||||
|
||||
private fun inplacemodificationWordWithMemread(name: String, dt: DataType, operator: String, memread: PtMemoryByte) {
|
||||
when (operator) {
|
||||
"+" -> {
|
||||
|
@ -1611,7 +1627,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||
asmgen.out(" lda $name+1 | and #>$value | sta $name+1")
|
||||
}
|
||||
value < 0x0100 -> {
|
||||
asmgen.out(" lda $name | and #$value | sta $name")
|
||||
immediateAndInplace(name, value)
|
||||
if(asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||
asmgen.out(" stz $name+1")
|
||||
else
|
||||
|
@ -1624,7 +1640,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||
when {
|
||||
value == 0 -> {}
|
||||
value and 255 == 0 -> asmgen.out(" lda $name+1 | ora #>$value | sta $name+1")
|
||||
value < 0x0100 -> asmgen.out(" lda $name | ora #$value | sta $name")
|
||||
value < 0x0100 -> immediateOrInplace(name, value)
|
||||
else -> asmgen.out(" lda $name | ora #<$value | sta $name | lda $name+1 | ora #>$value | sta $name+1")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
TODO
|
||||
====
|
||||
|
||||
- use TRB/TSB instructions more on the x16 such as when ack vera irq bits cx16.VERA_ISR |= 4
|
||||
xx |= %0001000, xx &= %1110111
|
||||
- new cx16 master irq handler:
|
||||
- describe the order in which irq sources are handled, should they occur at the same time
|
||||
- change the order? line, vsync, sprcol, aflow?
|
||||
|
||||
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||
|
||||
|
|
|
@ -1,88 +1,25 @@
|
|||
%import palette
|
||||
%import textio
|
||||
%import syslib
|
||||
%zeropage basicsafe
|
||||
|
||||
; Example that shows a way to handle multiple IRQ sources on the X16.
|
||||
; This uses the "OLD" way using the interrupt handler routines in sys.
|
||||
; (see multi-irq-new example to do it the "new" way)
|
||||
; Currently only Vera interrupts are supported. VIA irqs are an exercise for the reader.
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
sys.set_rasterline(150)
|
||||
sys.set_irq(&irq.master_handler) ; ..will just enable vsync..
|
||||
cx16.VERA_IEN |= 2 ; .. so also enable line irq here.
|
||||
ubyte xx = 1
|
||||
uword ww=1
|
||||
|
||||
txt.print("\n\n\nx16 irq handlers installed (old style)\n")
|
||||
txt.print("red = vsync irq\n")
|
||||
txt.print("green = first line irq\n")
|
||||
txt.print("blue = second line irq\n")
|
||||
}
|
||||
}
|
||||
|
||||
irq {
|
||||
sub master_handler() -> bool {
|
||||
ubyte irqsrc = cx16.VERA_ISR & cx16.VERA_IEN ; only consider sources that are enabled
|
||||
ror(irqsrc)
|
||||
if_cs {
|
||||
vsync_irq()
|
||||
return true ; run system IRQ handler. It will ack the vsync IRQ as well.
|
||||
}
|
||||
ror(irqsrc)
|
||||
if_cs {
|
||||
line_irq()
|
||||
cx16.VERA_ISR |= 2 ; ack the irq
|
||||
return false
|
||||
}
|
||||
ror(irqsrc)
|
||||
if_cs {
|
||||
sprcol_irq()
|
||||
cx16.VERA_ISR |= 4 ; ack the irq
|
||||
return false
|
||||
}
|
||||
ror(irqsrc)
|
||||
if_cs {
|
||||
aflow_irq()
|
||||
; note: AFLOW can only be cleared by filling the audio FIFO for at least 1/4. Not via the ISR bit.
|
||||
return false
|
||||
}
|
||||
|
||||
; weird irq
|
||||
return false
|
||||
}
|
||||
|
||||
sub vsync_irq() {
|
||||
cx16.save_vera_context()
|
||||
palette.set_color(0, $f00)
|
||||
repeat 1000 {
|
||||
cx16.r0++
|
||||
}
|
||||
palette.set_color(0, $000)
|
||||
cx16.restore_vera_context()
|
||||
}
|
||||
|
||||
sub line_irq() {
|
||||
cx16.save_vera_context()
|
||||
if cx16.VERA_SCANLINE_L==150 {
|
||||
palette.set_color(0, $0f0)
|
||||
sys.set_rasterline(200) ; prepare next line irq
|
||||
} else {
|
||||
palette.set_color(0, $00f)
|
||||
sys.set_rasterline(150) ; back to first line irq
|
||||
}
|
||||
repeat 500 {
|
||||
cx16.r0++
|
||||
}
|
||||
palette.set_color(0, $000)
|
||||
cx16.restore_vera_context()
|
||||
}
|
||||
|
||||
sub sprcol_irq() {
|
||||
; nothing here yet
|
||||
}
|
||||
|
||||
sub aflow_irq() {
|
||||
; nothing here yet
|
||||
|
||||
xx |= %0001000
|
||||
txt.print_ubbin(xx, true)
|
||||
txt.nl()
|
||||
xx &= %11110111
|
||||
txt.print_ubbin(xx, true)
|
||||
txt.nl()
|
||||
|
||||
|
||||
ww |= %0001000
|
||||
txt.print_uwbin(ww, true)
|
||||
txt.nl()
|
||||
ww &= %11110111
|
||||
txt.print_uwbin(ww, true)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user