mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-28 01:29:44 +00:00
Implemented new interrupt system supporting more platforms and CPUs. Closes #599
This commit is contained in:
parent
cd6c33a92c
commit
089125ff5e
618
src/main/fragment/cache/fragment-cache-csg65ce02.asm
vendored
618
src/main/fragment/cache/fragment-cache-csg65ce02.asm
vendored
@ -1,244 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE 140bf2a915 140bf2c716
|
||||
//FRAGMENT vbuzz=vbuc1
|
||||
ldz #{c1}
|
||||
//FRAGMENT vbuzz_lt_vbuc1_then_la1
|
||||
cpz #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT pbuc1_derefidx_vbuzz=vbuzz
|
||||
tza
|
||||
tax
|
||||
sta {c1},x
|
||||
//FRAGMENT vbuzz=_inc_vbuzz
|
||||
inz
|
||||
//FRAGMENT vbsz1=_deref_pbsc1
|
||||
lda {c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=_neg_vbsz2
|
||||
lda {z2}
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT _deref_pbsc1=vbsz1
|
||||
lda {z1}
|
||||
sta {c1}
|
||||
//FRAGMENT vbsz1=vbsz2_ror_2
|
||||
lda {z2}
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsaa=_deref_pbsc1
|
||||
lda {c1}
|
||||
//FRAGMENT vbsxx=_deref_pbsc1
|
||||
ldx {c1}
|
||||
//FRAGMENT vbsz1=_neg_vbsaa
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT vbsaa=_neg_vbsz1
|
||||
lda {z1}
|
||||
neg
|
||||
//FRAGMENT vbsaa=_neg_vbsaa
|
||||
neg
|
||||
//FRAGMENT vbsaa=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
//FRAGMENT vbsaa=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
//FRAGMENT vbsaa=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
//FRAGMENT vbsxx=_neg_vbsz1
|
||||
lda {z1}
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsxx=_neg_vbsaa
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsxx=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsxx=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsxx=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsyy=_neg_vbsz1
|
||||
lda {z1}
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbsyy=_neg_vbsaa
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbsyy=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbsyy=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbsyy=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbszz=_neg_vbsz1
|
||||
lda {z1}
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT vbszz=_neg_vbsaa
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT vbszz=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT vbszz=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT vbszz=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT _deref_pbsc1=vbsaa
|
||||
sta {c1}
|
||||
//FRAGMENT vbsz1=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsaa=vbsz1_ror_2
|
||||
lda {z1}
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsaa=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsaa=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsaa=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsaa=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsxx=vbsz1_ror_2
|
||||
lda {z1}
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsxx=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsxx=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsxx=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsxx=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsyy=vbsz1_ror_2
|
||||
lda {z1}
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbsyy=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbsyy=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbsyy=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbsyy=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbszz=vbsz1_ror_2
|
||||
lda {z1}
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbszz=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbsyy=_deref_pbsc1
|
||||
ldy {c1}
|
||||
//FRAGMENT vbszz=_deref_pbsc1
|
||||
lda {c1}
|
||||
taz
|
||||
//FRAGMENT _deref_pbsc1=vbsxx
|
||||
stx {c1}
|
||||
//FRAGMENT _deref_pbsc1=vbsyy
|
||||
sty {c1}
|
||||
//FRAGMENT _deref_pbsc1=vbszz
|
||||
tza
|
||||
sta {c1}
|
||||
//KICKC FRAGMENT CACHE 149935006b 1499351e94
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
@ -324,8 +84,8 @@ inc {z1}+1
|
||||
inc {z1}
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=vbuc1
|
||||
lda #{c1}
|
||||
ldy {z2}
|
||||
sta ({z1}),y
|
||||
ldz {z2}
|
||||
sta ({z1}),z
|
||||
//FRAGMENT vbuz1=_deref_pbuz2
|
||||
ldy #0
|
||||
lda ({z2}),y
|
||||
@ -385,8 +145,8 @@ sta {c1},y
|
||||
dec {z1}
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=vbuz3
|
||||
lda {z3}
|
||||
ldy {z2}
|
||||
sta ({z1}),y
|
||||
ldz {z2}
|
||||
sta ({z1}),z
|
||||
//FRAGMENT vbuz1_neq_vbuc1_then_la1
|
||||
lda #{c1}
|
||||
cmp {z1}
|
||||
@ -719,12 +479,20 @@ sta {c1},y
|
||||
cmp #{c1}
|
||||
beq {la1}
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=vbuaa
|
||||
ldy {z2}
|
||||
sta ({z1}),y
|
||||
ldz {z2}
|
||||
sta ({z1}),z
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=vbuxx
|
||||
txa
|
||||
ldz {z2}
|
||||
sta ({z1}),z
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=vbuyy
|
||||
tya
|
||||
ldz {z2}
|
||||
sta ({z1}),z
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=vbuzz
|
||||
tza
|
||||
ldz {z2}
|
||||
sta ({z1}),z
|
||||
//FRAGMENT vbuaa=_byte_vwuz1
|
||||
lda {z1}
|
||||
//FRAGMENT vbuxx=_byte_vwuz1
|
||||
@ -925,34 +693,6 @@ eor #$ff
|
||||
sec
|
||||
adc {z1}
|
||||
tax
|
||||
//FRAGMENT vbszz=vbsz1_minus_vbsz2
|
||||
lda {z1}
|
||||
sec
|
||||
sbc {z2}
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsz1_minus_vbsaa
|
||||
eor #$ff
|
||||
sec
|
||||
adc {z1}
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsz1_minus_vbsxx
|
||||
txa
|
||||
eor #$ff
|
||||
sec
|
||||
adc {z1}
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsz1_minus_vbsyy
|
||||
tya
|
||||
eor #$ff
|
||||
sec
|
||||
adc {z1}
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsz1_minus_vbszz
|
||||
tza
|
||||
eor #$ff
|
||||
sec
|
||||
adc {z1}
|
||||
taz
|
||||
//FRAGMENT vbsz1=vbsxx_minus_vbsz2
|
||||
txa
|
||||
sec
|
||||
@ -1005,32 +745,6 @@ stz $ff
|
||||
sec
|
||||
sbc $ff
|
||||
tax
|
||||
//FRAGMENT vbszz=vbsxx_minus_vbsz1
|
||||
txa
|
||||
sec
|
||||
sbc {z1}
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsxx_minus_vbsaa
|
||||
sta $ff
|
||||
txa
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsxx_minus_vbsxx
|
||||
lda #0
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsxx_minus_vbsyy
|
||||
txa
|
||||
sty $ff
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsxx_minus_vbszz
|
||||
txa
|
||||
stz $ff
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbsz1=vbsyy_minus_vbsz2
|
||||
tya
|
||||
sec
|
||||
@ -1083,32 +797,6 @@ stz $ff
|
||||
sec
|
||||
sbc $ff
|
||||
tax
|
||||
//FRAGMENT vbszz=vbsyy_minus_vbsz1
|
||||
tya
|
||||
sec
|
||||
sbc {z1}
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsyy_minus_vbsaa
|
||||
sta $ff
|
||||
tya
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsyy_minus_vbsxx
|
||||
tya
|
||||
stx $ff
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsyy_minus_vbsyy
|
||||
lda #0
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsyy_minus_vbszz
|
||||
tya
|
||||
stz $ff
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbsz1=vbszz_minus_vbsz2
|
||||
tza
|
||||
sec
|
||||
@ -1165,34 +853,6 @@ tax
|
||||
tza
|
||||
lda #0
|
||||
tax
|
||||
//FRAGMENT vbszz=vbszz_minus_vbsz1
|
||||
tza
|
||||
sec
|
||||
sbc {z1}
|
||||
taz
|
||||
//FRAGMENT vbszz=vbszz_minus_vbsaa
|
||||
tay
|
||||
tza
|
||||
sty $ff
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbszz=vbszz_minus_vbsxx
|
||||
tza
|
||||
stx $ff
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbszz=vbszz_minus_vbsyy
|
||||
tza
|
||||
sty $ff
|
||||
sec
|
||||
sbc $ff
|
||||
taz
|
||||
//FRAGMENT vbszz=vbszz_minus_vbszz
|
||||
tza
|
||||
lda #0
|
||||
taz
|
||||
//FRAGMENT vbsxx_ge_0_then_la1
|
||||
cpx #0
|
||||
bpl {la1}
|
||||
@ -2220,6 +1880,8 @@ cpx {z1}
|
||||
bcs {la1}
|
||||
//FRAGMENT vbuxx=vbuc1
|
||||
ldx #{c1}
|
||||
//FRAGMENT vbuzz=vbuc1
|
||||
ldz #{c1}
|
||||
//FRAGMENT vbuzz=vbuz1
|
||||
ldz {z1}
|
||||
//FRAGMENT vbuz1=vbuzz
|
||||
@ -2234,6 +1896,8 @@ inx
|
||||
ldy #{c1}
|
||||
//FRAGMENT vbuyy=_inc_vbuyy
|
||||
iny
|
||||
//FRAGMENT vbuzz=_inc_vbuzz
|
||||
inz
|
||||
//FRAGMENT vbuz1_ge_vbuxx_then_la1
|
||||
lda {z1}
|
||||
stx $ff
|
||||
@ -2290,6 +1954,9 @@ bcc {la1}
|
||||
cpy #{c1}
|
||||
bcc {la1}
|
||||
beq {la1}
|
||||
//FRAGMENT vbuzz_lt_vbuc1_then_la1
|
||||
cpz #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT vbuzz_le_vbuc1_then_la1
|
||||
cpz #{c1}
|
||||
bcc {la1}
|
||||
@ -2320,17 +1987,9 @@ taz
|
||||
//FRAGMENT vbuyy_eq_vbuc1_then_la1
|
||||
cpy #{c1}
|
||||
beq {la1}
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=vbuyy
|
||||
tya
|
||||
ldy {z2}
|
||||
sta ({z1}),y
|
||||
//FRAGMENT vbuzz_eq_vbuc1_then_la1
|
||||
cpz #{c1}
|
||||
beq {la1}
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=vbuzz
|
||||
tza
|
||||
ldz {z2}
|
||||
sta ({z1}),z
|
||||
//FRAGMENT vbuz1_lt_vbuxx_then_la1
|
||||
cpx {z1}
|
||||
beq !+
|
||||
@ -2519,3 +2178,236 @@ sta {z1}+1
|
||||
asw {z1}
|
||||
asw {z1}
|
||||
asw {z1}
|
||||
//FRAGMENT pbuc1_derefidx_vbuzz=vbuzz
|
||||
tza
|
||||
tax
|
||||
sta {c1},x
|
||||
//FRAGMENT vbsz1=_deref_pbsc1
|
||||
lda {c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=_neg_vbsz2
|
||||
lda {z2}
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT _deref_pbsc1=vbsz1
|
||||
lda {z1}
|
||||
sta {c1}
|
||||
//FRAGMENT vbsz1=vbsz2_ror_2
|
||||
lda {z2}
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsaa=_deref_pbsc1
|
||||
lda {c1}
|
||||
//FRAGMENT vbsxx=_deref_pbsc1
|
||||
ldx {c1}
|
||||
//FRAGMENT vbsz1=_neg_vbsaa
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
sta {z1}
|
||||
//FRAGMENT vbsaa=_neg_vbsz1
|
||||
lda {z1}
|
||||
neg
|
||||
//FRAGMENT vbsaa=_neg_vbsaa
|
||||
neg
|
||||
//FRAGMENT vbsaa=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
//FRAGMENT vbsaa=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
//FRAGMENT vbsaa=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
//FRAGMENT vbsxx=_neg_vbsz1
|
||||
lda {z1}
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsxx=_neg_vbsaa
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsxx=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsxx=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsxx=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
tax
|
||||
//FRAGMENT vbsyy=_neg_vbsz1
|
||||
lda {z1}
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbsyy=_neg_vbsaa
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbsyy=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbsyy=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbsyy=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
tay
|
||||
//FRAGMENT vbszz=_neg_vbsz1
|
||||
lda {z1}
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT vbszz=_neg_vbsaa
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT vbszz=_neg_vbsxx
|
||||
txa
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT vbszz=_neg_vbsyy
|
||||
tya
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT vbszz=_neg_vbszz
|
||||
tza
|
||||
neg
|
||||
taz
|
||||
//FRAGMENT _deref_pbsc1=vbsaa
|
||||
sta {c1}
|
||||
//FRAGMENT vbsz1=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsz1=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
sta {z1}
|
||||
//FRAGMENT vbsaa=vbsz1_ror_2
|
||||
lda {z1}
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsaa=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsaa=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsaa=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsaa=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
//FRAGMENT vbsxx=vbsz1_ror_2
|
||||
lda {z1}
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsxx=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsxx=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsxx=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsxx=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
tax
|
||||
//FRAGMENT vbsyy=vbsz1_ror_2
|
||||
lda {z1}
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbsyy=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbsyy=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbsyy=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbsyy=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
tay
|
||||
//FRAGMENT vbszz=vbsz1_ror_2
|
||||
lda {z1}
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsaa_ror_2
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsxx_ror_2
|
||||
txa
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbszz=vbsyy_ror_2
|
||||
tya
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbszz=vbszz_ror_2
|
||||
tza
|
||||
asr
|
||||
asr
|
||||
taz
|
||||
//FRAGMENT vbsyy=_deref_pbsc1
|
||||
ldy {c1}
|
||||
//FRAGMENT vbszz=_deref_pbsc1
|
||||
lda {c1}
|
||||
taz
|
||||
//FRAGMENT _deref_pbsc1=vbsxx
|
||||
stx {c1}
|
||||
//FRAGMENT _deref_pbsc1=vbsyy
|
||||
sty {c1}
|
||||
//FRAGMENT _deref_pbsc1=vbszz
|
||||
tza
|
||||
sta {c1}
|
||||
|
1391
src/main/fragment/cache/fragment-cache-mega45gs02.asm
vendored
1391
src/main/fragment/cache/fragment-cache-mega45gs02.asm
vendored
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE 140bf2a915 140bf2c716
|
||||
//KICKC FRAGMENT CACHE 149935006b 1499351e94
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
|
20856
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
20856
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
File diff suppressed because it is too large
Load Diff
1130
src/main/fragment/cache/fragment-cache-rom6502x.asm
vendored
Normal file
1130
src/main/fragment/cache/fragment-cache-rom6502x.asm
vendored
Normal file
File diff suppressed because it is too large
Load Diff
701
src/main/fragment/cache/fragment-cache-wdc65c02.asm
vendored
701
src/main/fragment/cache/fragment-cache-wdc65c02.asm
vendored
@ -1,4 +1,273 @@
|
||||
//KICKC FRAGMENT CACHE 140bf2a915 140bf2c716
|
||||
//KICKC FRAGMENT CACHE 149935006b 1499351e94
|
||||
//FRAGMENT vwuz1=vwuc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT isr_rom_sys_cx16_entry
|
||||
|
||||
//FRAGMENT vwuz1=_inc_vwuz1
|
||||
inc {z1}
|
||||
bne !+
|
||||
inc {z1}+1
|
||||
!:
|
||||
//FRAGMENT vwuz1_neq_vbuc1_then_la1
|
||||
NO_SYNTHESIS
|
||||
//FRAGMENT vwuz1_neq_vwuc1_then_la1
|
||||
lda {z1}+1
|
||||
cmp #>{c1}
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
cmp #<{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT vwuz1=vbuc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=_dec_vwuz1
|
||||
lda {z1}
|
||||
bne !+
|
||||
dec {z1}+1
|
||||
!:
|
||||
dec {z1}
|
||||
//FRAGMENT vwuz1=vwuz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1=pbuc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1_lt_vbuc1_then_la1
|
||||
lda {z1}
|
||||
cmp #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT _deref_pbuc1=vbuc2
|
||||
lda #{c2}
|
||||
sta {c1}
|
||||
//FRAGMENT isr_rom_sys_cx16_exit
|
||||
jmp $e034
|
||||
//FRAGMENT vwuz1=vwuz2_rol_1
|
||||
lda {z2}
|
||||
asl
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
rol
|
||||
sta {z1}+1
|
||||
//FRAGMENT pwuz1=pwuc1_plus_vwuz2
|
||||
clc
|
||||
lda {z2}
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT _deref_pwuc1=_deref_pwuz1
|
||||
ldy #0
|
||||
lda ({z1}),y
|
||||
sta {c1}
|
||||
iny
|
||||
lda ({z1}),y
|
||||
sta {c1}+1
|
||||
//FRAGMENT pvoz1=pvoz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pvoz1=pvoc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1=pbuz1_plus_vbuc1
|
||||
lda #{c1}
|
||||
clc
|
||||
adc {z1}
|
||||
sta {z1}
|
||||
bcc !+
|
||||
inc {z1}+1
|
||||
!:
|
||||
//FRAGMENT vwuz1=vwuz1_plus_vbuc1
|
||||
lda #{c1}
|
||||
clc
|
||||
adc {z1}
|
||||
sta {z1}
|
||||
bcc !+
|
||||
inc {z1}+1
|
||||
!:
|
||||
//FRAGMENT vwuz1_lt_vbuc1_then_la1
|
||||
lda {z1}+1
|
||||
bne !+
|
||||
lda {z1}
|
||||
cmp #{c1}
|
||||
bcc {la1}
|
||||
!:
|
||||
//FRAGMENT vwuz1=vwuz1_minus_vbuc1
|
||||
sec
|
||||
lda {z1}
|
||||
sbc #{c1}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
sbc #0
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuz1=_inc_vbuz1
|
||||
inc {z1}
|
||||
//FRAGMENT _deref_pbuc1=_deref_pbuc1_band_vbuc2
|
||||
lda #{c2}
|
||||
and {c1}
|
||||
sta {c1}
|
||||
//FRAGMENT _deref_pbuc1=_deref_pbuc1_bor_vbuc2
|
||||
lda #{c2}
|
||||
ora {c1}
|
||||
sta {c1}
|
||||
//FRAGMENT _deref_qprc1=pprc2
|
||||
lda #<{c2}
|
||||
sta {c1}
|
||||
lda #>{c2}
|
||||
sta {c1}+1
|
||||
//FRAGMENT _deref_pwuc1=_deref_pwuc1_plus_vbuc2
|
||||
NO_SYNTHESIS
|
||||
//FRAGMENT _deref_pwuc1=_deref_pwuc1_plus_vbsc2
|
||||
NO_SYNTHESIS
|
||||
//FRAGMENT _deref_pwuc1=_deref_pwuc1_plus_vwuc2
|
||||
lda #<{c2}
|
||||
clc
|
||||
adc {c1}
|
||||
sta {c1}
|
||||
lda #>{c2}
|
||||
adc {c1}+1
|
||||
sta {c1}+1
|
||||
//FRAGMENT vbuz1=_lo_pvoz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT _deref_pbuc1=vbuz1
|
||||
lda {z1}
|
||||
sta {c1}
|
||||
//FRAGMENT vbuz1=_hi_pvoz2
|
||||
lda {z2}+1
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuz2
|
||||
lda #{c1}
|
||||
ora {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT pbuz1=pbuz2_plus_vwuz3
|
||||
lda {z2}
|
||||
clc
|
||||
adc {z3}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc {z3}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1=pbuz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1_neq_pbuz2_then_la1
|
||||
lda {z1}+1
|
||||
cmp {z2}+1
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
cmp {z2}
|
||||
bne {la1}
|
||||
//FRAGMENT _deref_pbuc1=_deref_pbuz1
|
||||
ldy #0
|
||||
lda ({z1}),y
|
||||
sta {c1}
|
||||
//FRAGMENT pbuz1=_inc_pbuz1
|
||||
inc {z1}
|
||||
bne !+
|
||||
inc {z1}+1
|
||||
!:
|
||||
//FRAGMENT vbuaa_lt_vbuc1_then_la1
|
||||
cmp #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT vbuaa=_lo_pvoz1
|
||||
lda {z1}
|
||||
//FRAGMENT vbuxx=_lo_pvoz1
|
||||
ldx {z1}
|
||||
//FRAGMENT _deref_pbuc1=vbuaa
|
||||
sta {c1}
|
||||
//FRAGMENT vbuaa=_hi_pvoz1
|
||||
lda {z1}+1
|
||||
//FRAGMENT vbuxx=_hi_pvoz1
|
||||
ldx {z1}+1
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuz1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuz1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuz1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
tay
|
||||
//FRAGMENT vbuxx_lt_vbuc1_then_la1
|
||||
cpx #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT _deref_pbuc1=vbuxx
|
||||
stx {c1}
|
||||
//FRAGMENT vbuyy=_lo_pvoz1
|
||||
ldy {z1}
|
||||
//FRAGMENT _deref_pbuc1=vbuyy
|
||||
sty {c1}
|
||||
//FRAGMENT vbuyy=_hi_pvoz1
|
||||
ldy {z1}+1
|
||||
//FRAGMENT vbuxx=vbuc1
|
||||
ldx #{c1}
|
||||
//FRAGMENT pbuz1=pbuz2_plus_vwuz1
|
||||
lda {z1}
|
||||
clc
|
||||
adc {z2}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc {z2}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pwuz1=pwuc1_plus_vwuz1
|
||||
clc
|
||||
lda {z1}
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuz1=_deref_pbuc1
|
||||
lda {c1}
|
||||
sta {z1}
|
||||
@ -6,9 +275,6 @@ sta {z1}
|
||||
lda {z2}
|
||||
inc
|
||||
sta {z1}
|
||||
//FRAGMENT _deref_pbuc1=vbuz1
|
||||
lda {z1}
|
||||
sta {c1}
|
||||
//FRAGMENT vbuaa=_deref_pbuc1
|
||||
lda {c1}
|
||||
//FRAGMENT vbuxx=_deref_pbuc1
|
||||
@ -19,8 +285,6 @@ sta {z1}
|
||||
//FRAGMENT vbuz1=vbuxx_plus_1
|
||||
inx
|
||||
stx {z1}
|
||||
//FRAGMENT _deref_pbuc1=vbuaa
|
||||
sta {c1}
|
||||
//FRAGMENT vbuyy=_deref_pbuc1
|
||||
ldy {c1}
|
||||
//FRAGMENT vbuz1=vbuyy_plus_1
|
||||
@ -40,8 +304,6 @@ inc
|
||||
//FRAGMENT vbuxx=vbuz1_plus_1
|
||||
ldx {z1}
|
||||
inx
|
||||
//FRAGMENT _deref_pbuc1=vbuxx
|
||||
stx {c1}
|
||||
//FRAGMENT vbuxx=vbuaa_plus_1
|
||||
tax
|
||||
inx
|
||||
@ -54,8 +316,6 @@ tax
|
||||
//FRAGMENT vbuyy=vbuz1_plus_1
|
||||
ldy {z1}
|
||||
iny
|
||||
//FRAGMENT _deref_pbuc1=vbuyy
|
||||
sty {c1}
|
||||
//FRAGMENT vbuyy=vbuaa_plus_1
|
||||
tay
|
||||
iny
|
||||
@ -65,24 +325,92 @@ inc
|
||||
tay
|
||||
//FRAGMENT vbuyy=vbuyy_plus_1
|
||||
iny
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
//FRAGMENT 0_neq_pbuc1_derefidx_vbuz1_then_la1
|
||||
ldy {z1}
|
||||
lda {c1},y
|
||||
cmp #0
|
||||
bne {la1}
|
||||
//FRAGMENT vbuz1=pbuc1_derefidx_vbuz2
|
||||
ldy {z2}
|
||||
lda {c1},y
|
||||
sta {z1}
|
||||
//FRAGMENT _deref_pbuc1=_deref_pbuc1_bor_vbuc2
|
||||
lda #{c2}
|
||||
ora {c1}
|
||||
sta {c1}
|
||||
//FRAGMENT _deref_pbuc1=_deref_pbuc1_band_vbuc2
|
||||
lda #{c2}
|
||||
and {c1}
|
||||
sta {c1}
|
||||
//FRAGMENT pbuz1=_inc_pbuz2
|
||||
clc
|
||||
lda {z2}
|
||||
adc #1
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1_neq_pbuc1_then_la1
|
||||
lda {z1}+1
|
||||
cmp #>{c1}
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
cmp #<{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT vbuz1=_lo_pbuz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=_hi_pbuz2
|
||||
lda {z2}+1
|
||||
sta {z1}
|
||||
//FRAGMENT 0_neq_pbuc1_derefidx_vbuaa_then_la1
|
||||
tay
|
||||
lda {c1},y
|
||||
cmp #0
|
||||
bne {la1}
|
||||
//FRAGMENT 0_neq_pbuc1_derefidx_vbuxx_then_la1
|
||||
lda {c1},x
|
||||
cmp #0
|
||||
bne {la1}
|
||||
//FRAGMENT 0_neq_pbuc1_derefidx_vbuyy_then_la1
|
||||
lda {c1},y
|
||||
cmp #0
|
||||
bne {la1}
|
||||
//FRAGMENT vbuz1=pbuc1_derefidx_vbuxx
|
||||
lda {c1},x
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=pbuc1_derefidx_vbuyy
|
||||
lda {c1},y
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=pbuc1_derefidx_vbuz1
|
||||
ldy {z1}
|
||||
lda {c1},y
|
||||
//FRAGMENT vbuaa=pbuc1_derefidx_vbuxx
|
||||
lda {c1},x
|
||||
//FRAGMENT vbuaa=pbuc1_derefidx_vbuyy
|
||||
lda {c1},y
|
||||
//FRAGMENT vbuxx=pbuc1_derefidx_vbuz1
|
||||
ldy {z1}
|
||||
ldx {c1},y
|
||||
//FRAGMENT vbuaa=_lo_pbuz1
|
||||
lda {z1}
|
||||
//FRAGMENT vbuxx=_lo_pbuz1
|
||||
ldx {z1}
|
||||
//FRAGMENT vbuaa=_hi_pbuz1
|
||||
lda {z1}+1
|
||||
//FRAGMENT vbuxx=_hi_pbuz1
|
||||
ldx {z1}+1
|
||||
//FRAGMENT vbuyy=_lo_pbuz1
|
||||
ldy {z1}
|
||||
//FRAGMENT vbuyy=_hi_pbuz1
|
||||
ldy {z1}+1
|
||||
//FRAGMENT vbuyy=pbuc1_derefidx_vbuz1
|
||||
ldx {z1}
|
||||
ldy {c1},x
|
||||
//FRAGMENT vbuyy=vbuc1
|
||||
ldy #{c1}
|
||||
//FRAGMENT vbuxx=pbuc1_derefidx_vbuyy
|
||||
ldx {c1},y
|
||||
//FRAGMENT vbuyy=_inc_vbuyy
|
||||
iny
|
||||
//FRAGMENT isr_rom_min_cx16_entry
|
||||
|
||||
//FRAGMENT vbuz1_neq_vbuc1_then_la1
|
||||
lda #{c1}
|
||||
cmp {z1}
|
||||
bne {la1}
|
||||
//FRAGMENT _deref_pbuc1=vbuc2
|
||||
lda #{c2}
|
||||
sta {c1}
|
||||
//FRAGMENT vbuz1=_dec_vbuz1
|
||||
dec {z1}
|
||||
//FRAGMENT vbuz1_neq_0_then_la1
|
||||
@ -93,64 +421,11 @@ bne {la1}
|
||||
lda {z1}
|
||||
cmp #{c1}
|
||||
bcs {la1}
|
||||
//FRAGMENT vbuz1=_inc_vbuz1
|
||||
inc {z1}
|
||||
//FRAGMENT _deref_pbuc1=pbuc2_derefidx_vbuz1
|
||||
ldy {z1}
|
||||
lda {c2},y
|
||||
sta {c1}
|
||||
//FRAGMENT vbuz1_lt_vbuc1_then_la1
|
||||
lda {z1}
|
||||
cmp #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT _deref_qprc1=pprc2
|
||||
lda #<{c2}
|
||||
sta {c1}
|
||||
lda #>{c2}
|
||||
sta {c1}+1
|
||||
//FRAGMENT vbuaa_neq_vbuc1_then_la1
|
||||
cmp #{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT _deref_pbuc1=pbuc2_derefidx_vbuaa
|
||||
tay
|
||||
lda {c2},y
|
||||
sta {c1}
|
||||
//FRAGMENT _deref_pbuc1=pbuc2_derefidx_vbuxx
|
||||
lda {c2},x
|
||||
sta {c1}
|
||||
//FRAGMENT _deref_pbuc1=pbuc2_derefidx_vbuyy
|
||||
lda {c2},y
|
||||
sta {c1}
|
||||
//FRAGMENT vbuaa_lt_vbuc1_then_la1
|
||||
cmp #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT vbuxx_neq_vbuc1_then_la1
|
||||
cpx #{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT vbuaa=vbuc1
|
||||
lda #{c1}
|
||||
//FRAGMENT vbuaa=_inc_vbuaa
|
||||
inc
|
||||
//FRAGMENT vbuxx=vbuc1
|
||||
ldx #{c1}
|
||||
//FRAGMENT vbuxx_lt_vbuc1_then_la1
|
||||
cpx #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//FRAGMENT vbuyy=vbuc1
|
||||
ldy #{c1}
|
||||
//FRAGMENT vbuyy_lt_vbuc1_then_la1
|
||||
cpy #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT vbuyy=_inc_vbuyy
|
||||
iny
|
||||
//FRAGMENT vbuyy_neq_vbuc1_then_la1
|
||||
cpy #{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT vbuz1=vbuz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT isr_rom_min_cx16_exit
|
||||
jmp $e049
|
||||
//FRAGMENT pbuz1=pbuc1_plus_pbuc2_derefidx_vbuz2
|
||||
ldy {z2}
|
||||
lda {c2},y
|
||||
@ -169,27 +444,17 @@ sta {z1}
|
||||
ldy {z2}
|
||||
lda {c1},y
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1=pbuc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1_neq_pbuc1_then_la1
|
||||
lda {z1}+1
|
||||
cmp #>{c1}
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
cmp #<{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT _deref_pbuc1=pbuc2_derefidx_vbuz1
|
||||
ldy {z1}
|
||||
lda {c2},y
|
||||
sta {c1}
|
||||
//FRAGMENT _deref_pbuz1=vbuc1
|
||||
lda #{c1}
|
||||
ldy #0
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1=_inc_pbuz1
|
||||
inc {z1}
|
||||
bne !+
|
||||
inc {z1}+1
|
||||
!:
|
||||
//FRAGMENT vbuaa_neq_vbuc1_then_la1
|
||||
cmp #{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT vbuaa=vbuz1
|
||||
lda {z1}
|
||||
//FRAGMENT vbuxx=vbuz1
|
||||
@ -241,232 +506,28 @@ sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuyy=pbuc1_derefidx_vbuyy
|
||||
lda {c1},y
|
||||
sta ({z1}),y
|
||||
//FRAGMENT 0_neq_pbuc1_derefidx_vbuz1_then_la1
|
||||
ldy {z1}
|
||||
lda {c1},y
|
||||
cmp #0
|
||||
bne {la1}
|
||||
//FRAGMENT pbuz1=pbuz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuz1=pbuc1_derefidx_vbuz2
|
||||
ldy {z2}
|
||||
lda {c1},y
|
||||
sta {z1}
|
||||
//FRAGMENT pbuz1=_inc_pbuz2
|
||||
clc
|
||||
lda {z2}
|
||||
adc #1
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuz1=_lo_pbuz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=_hi_pbuz2
|
||||
lda {z2}+1
|
||||
sta {z1}
|
||||
//FRAGMENT 0_neq_pbuc1_derefidx_vbuaa_then_la1
|
||||
//FRAGMENT _deref_pbuc1=pbuc2_derefidx_vbuaa
|
||||
tay
|
||||
lda {c1},y
|
||||
cmp #0
|
||||
bne {la1}
|
||||
//FRAGMENT 0_neq_pbuc1_derefidx_vbuxx_then_la1
|
||||
lda {c1},x
|
||||
cmp #0
|
||||
bne {la1}
|
||||
//FRAGMENT 0_neq_pbuc1_derefidx_vbuyy_then_la1
|
||||
lda {c1},y
|
||||
cmp #0
|
||||
bne {la1}
|
||||
//FRAGMENT vbuz1=pbuc1_derefidx_vbuxx
|
||||
lda {c1},x
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=pbuc1_derefidx_vbuyy
|
||||
lda {c1},y
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=pbuc1_derefidx_vbuz1
|
||||
ldy {z1}
|
||||
lda {c1},y
|
||||
//FRAGMENT vbuaa=pbuc1_derefidx_vbuxx
|
||||
lda {c1},x
|
||||
//FRAGMENT vbuaa=pbuc1_derefidx_vbuyy
|
||||
lda {c1},y
|
||||
//FRAGMENT vbuxx=pbuc1_derefidx_vbuz1
|
||||
ldy {z1}
|
||||
ldx {c1},y
|
||||
//FRAGMENT vbuaa=_lo_pbuz1
|
||||
lda {z1}
|
||||
//FRAGMENT vbuxx=_lo_pbuz1
|
||||
ldx {z1}
|
||||
//FRAGMENT vbuaa=_hi_pbuz1
|
||||
lda {z1}+1
|
||||
//FRAGMENT vbuxx=_hi_pbuz1
|
||||
ldx {z1}+1
|
||||
//FRAGMENT vbuyy=_lo_pbuz1
|
||||
ldy {z1}
|
||||
//FRAGMENT vbuyy=_hi_pbuz1
|
||||
ldy {z1}+1
|
||||
//FRAGMENT vbuyy=pbuc1_derefidx_vbuz1
|
||||
ldx {z1}
|
||||
ldy {c1},x
|
||||
//FRAGMENT vbuxx=pbuc1_derefidx_vbuyy
|
||||
ldx {c1},y
|
||||
//FRAGMENT vwuz1=vwuc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=_inc_vwuz1
|
||||
inc {z1}
|
||||
bne !+
|
||||
inc {z1}+1
|
||||
!:
|
||||
//FRAGMENT vwuz1_neq_vbuc1_then_la1
|
||||
NO_SYNTHESIS
|
||||
//FRAGMENT vwuz1_neq_vwuc1_then_la1
|
||||
lda {z1}+1
|
||||
cmp #>{c1}
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
cmp #<{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT vwuz1=vbuc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=_dec_vwuz1
|
||||
lda {z1}
|
||||
bne !+
|
||||
dec {z1}+1
|
||||
!:
|
||||
dec {z1}
|
||||
//FRAGMENT vwuz1=vwuz2_rol_1
|
||||
lda {z2}
|
||||
asl
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
rol
|
||||
sta {z1}+1
|
||||
//FRAGMENT pwuz1=pwuc1_plus_vwuz2
|
||||
clc
|
||||
lda {z2}
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT _deref_pwuc1=_deref_pwuz1
|
||||
ldy #0
|
||||
lda ({z1}),y
|
||||
lda {c2},y
|
||||
sta {c1}
|
||||
iny
|
||||
lda ({z1}),y
|
||||
sta {c1}+1
|
||||
//FRAGMENT pvoz1=pvoc1
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuz1=_lo_pvoz2
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=_hi_pvoz2
|
||||
lda {z2}+1
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuz2
|
||||
lda #{c1}
|
||||
ora {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT pbuz1=pbuz2_plus_vwuz3
|
||||
lda {z2}
|
||||
clc
|
||||
adc {z3}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc {z3}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1_neq_pbuz2_then_la1
|
||||
lda {z1}+1
|
||||
cmp {z2}+1
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
cmp {z2}
|
||||
bne {la1}
|
||||
//FRAGMENT _deref_pbuc1=_deref_pbuz1
|
||||
ldy #0
|
||||
lda ({z1}),y
|
||||
//FRAGMENT _deref_pbuc1=pbuc2_derefidx_vbuxx
|
||||
lda {c2},x
|
||||
sta {c1}
|
||||
//FRAGMENT vbuaa=_lo_pvoz1
|
||||
lda {z1}
|
||||
//FRAGMENT vbuxx=_lo_pvoz1
|
||||
ldx {z1}
|
||||
//FRAGMENT vbuaa=_hi_pvoz1
|
||||
lda {z1}+1
|
||||
//FRAGMENT vbuxx=_hi_pvoz1
|
||||
ldx {z1}+1
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuz1
|
||||
//FRAGMENT _deref_pbuc1=pbuc2_derefidx_vbuyy
|
||||
lda {c2},y
|
||||
sta {c1}
|
||||
//FRAGMENT vbuxx_neq_vbuc1_then_la1
|
||||
cpx #{c1}
|
||||
bne {la1}
|
||||
//FRAGMENT vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//FRAGMENT vbuyy_lt_vbuc1_then_la1
|
||||
cpy #{c1}
|
||||
bcc {la1}
|
||||
//FRAGMENT vbuaa=vbuc1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuz1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuz1
|
||||
lda #{c1}
|
||||
ora {z1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuxx
|
||||
txa
|
||||
ora #{c1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
//FRAGMENT vbuxx=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuc1_bor_vbuyy
|
||||
tya
|
||||
ora #{c1}
|
||||
tay
|
||||
//FRAGMENT vbuyy=_lo_pvoz1
|
||||
ldy {z1}
|
||||
//FRAGMENT vbuyy=_hi_pvoz1
|
||||
ldy {z1}+1
|
||||
//FRAGMENT pbuz1=pbuz2_plus_vwuz1
|
||||
lda {z1}
|
||||
clc
|
||||
adc {z2}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc {z2}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pwuz1=pwuc1_plus_vwuz1
|
||||
clc
|
||||
lda {z1}
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuaa=_inc_vbuaa
|
||||
inc
|
||||
//FRAGMENT vbuyy_neq_vbuc1_then_la1
|
||||
cpy #{c1}
|
||||
bne {la1}
|
||||
|
@ -0,0 +1,4 @@
|
||||
pha
|
||||
phx
|
||||
phy
|
||||
phz
|
@ -0,0 +1,5 @@
|
||||
plz
|
||||
ply
|
||||
plx
|
||||
pla
|
||||
rti
|
@ -0,0 +1,5 @@
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
@ -0,0 +1,6 @@
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
@ -0,0 +1 @@
|
||||
pha
|
@ -0,0 +1,2 @@
|
||||
pla
|
||||
rti
|
@ -0,0 +1,3 @@
|
||||
pha
|
||||
txa
|
||||
pha
|
@ -0,0 +1,4 @@
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
@ -0,0 +1,3 @@
|
||||
pha
|
||||
tya
|
||||
pha
|
@ -0,0 +1,4 @@
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
rti
|
@ -0,0 +1 @@
|
||||
rti
|
@ -0,0 +1 @@
|
||||
jmp $ea81
|
@ -0,0 +1 @@
|
||||
jmp $e049
|
@ -0,0 +1 @@
|
||||
jmp $ea31
|
@ -0,0 +1 @@
|
||||
jmp $e034
|
@ -0,0 +1,3 @@
|
||||
sta rega+1
|
||||
stx regx+1
|
||||
sty regy+1
|
@ -0,0 +1,4 @@
|
||||
rega: lda #0
|
||||
regx: ldx #0
|
||||
regy: ldy #0
|
||||
rti
|
@ -0,0 +1,2 @@
|
||||
sta rega+1
|
||||
stx regx+1
|
@ -0,0 +1,3 @@
|
||||
rega: lda #0
|
||||
regx: ldx #0
|
||||
rti
|
@ -0,0 +1,2 @@
|
||||
sta rega+1
|
||||
sty regy+1
|
@ -0,0 +1,3 @@
|
||||
rega: lda #0
|
||||
regy: ldy #0
|
||||
rti
|
@ -0,0 +1,2 @@
|
||||
pha
|
||||
phx
|
@ -0,0 +1,3 @@
|
||||
plx
|
||||
pla
|
||||
rti
|
@ -0,0 +1,2 @@
|
||||
pha
|
||||
phy
|
@ -0,0 +1,3 @@
|
||||
ply
|
||||
pla
|
||||
rti
|
@ -0,0 +1 @@
|
||||
phx
|
@ -0,0 +1,2 @@
|
||||
plx
|
||||
rti
|
@ -0,0 +1,3 @@
|
||||
pha
|
||||
phx
|
||||
phy
|
@ -0,0 +1,4 @@
|
||||
ply
|
||||
plx
|
||||
pla
|
||||
rti
|
@ -176,7 +176,10 @@ public class Compiler {
|
||||
if(encoding==null)
|
||||
encoding = StringEncoding.SCREENCODE_MIXED;
|
||||
|
||||
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(cParser, cFileContext, program, callingConvention, encoding);
|
||||
// Find default interrupt type
|
||||
String interruptType = program.getTargetPlatform().getInterruptType();
|
||||
|
||||
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(cParser, cFileContext, program, callingConvention, encoding, interruptType);
|
||||
pass0GenerateStatementSequence.generate();
|
||||
|
||||
pass1GenerateSSA();
|
||||
|
@ -156,7 +156,7 @@ public class AsmFragmentInstanceSpec {
|
||||
SymbolType nextVariationValue = variationIterator.next();
|
||||
// Find the next name
|
||||
String variationConstName = "c" + variationCurrentName.substring(variationCurrentName.length() - 1);
|
||||
String variationNextName = AsmFragmentInstanceSpecFactory.getTypePrefix(nextVariationValue) + variationConstName;
|
||||
String variationNextName = AsmFragmentInstanceSpecBuilder.getTypePrefix(nextVariationValue) + variationConstName;
|
||||
// Update bindings
|
||||
Value constValue = bindings.get(variationCurrentName);
|
||||
bindings.remove(variationCurrentName);
|
||||
|
@ -16,52 +16,107 @@ import dk.camelot64.kickc.model.types.*;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.lang.InternalError;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A fragment specification generated from a {@link Statement} used to load/synthesize an {@link AsmFragmentInstance} for creating ASM code for the statement
|
||||
*/
|
||||
public class AsmFragmentInstanceSpecFactory {
|
||||
public class AsmFragmentInstanceSpecBuilder {
|
||||
|
||||
/**
|
||||
* The symbol table.
|
||||
*/
|
||||
private Program program;
|
||||
private final Program program;
|
||||
|
||||
/**
|
||||
* Binding of named values in the fragment to values (constants, variables, ...) .
|
||||
*/
|
||||
private Map<String, Value> bindings;
|
||||
private final Map<String, Value> bindings;
|
||||
|
||||
/**
|
||||
* The created ASM fragment instance specification
|
||||
*/
|
||||
private AsmFragmentInstanceSpec asmFragmentInstanceSpec;
|
||||
private final AsmFragmentInstanceSpec asmFragmentInstanceSpec;
|
||||
|
||||
/** Indexing for zeropages/constants/labels */
|
||||
private int nextZpIdx = 1;
|
||||
private int nextMemIdx = 1;
|
||||
private int nextConstIdx = 1;
|
||||
private int nextLabelIdx = 1;
|
||||
|
||||
public Map<String, Value> getBindings() {
|
||||
return bindings;
|
||||
/**
|
||||
* Create a fragment instance spec factory for an interrupt routine (entry or exit)
|
||||
*
|
||||
* @param interruptTypeComplete The interrupt routine handler name - including "isr_" and "_entry"/_exit"
|
||||
* @param program The program
|
||||
* @return the fragment instance spec factory
|
||||
*/
|
||||
public static AsmFragmentInstanceSpecBuilder interrupt(String interruptTypeComplete, Program program) {
|
||||
Map<String, Value> bindings = new HashMap<>();
|
||||
String signature = interruptTypeComplete;
|
||||
ScopeRef codeScope = program.getScope().getRef();
|
||||
final AsmFragmentInstanceSpec fragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
|
||||
return new AsmFragmentInstanceSpecBuilder(program, bindings, fragmentInstanceSpec);
|
||||
}
|
||||
|
||||
public AsmFragmentInstanceSpecFactory(
|
||||
/**
|
||||
* Create a fragment instance spec factory for an interrupt routine entry
|
||||
*
|
||||
* @param interruptType The interrupt routine handle name
|
||||
* @param program The program
|
||||
* @return the fragment instance spec factory
|
||||
*/
|
||||
public static AsmFragmentInstanceSpecBuilder interruptEntry(String interruptType, Program program) {
|
||||
Map<String, Value> bindings = new HashMap<>();
|
||||
String signature = "isr_" + interruptType + "_entry";
|
||||
ScopeRef codeScope = program.getScope().getRef();
|
||||
final AsmFragmentInstanceSpec fragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
|
||||
return new AsmFragmentInstanceSpecBuilder(program, bindings, fragmentInstanceSpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fragment instance spec factory for an interrupt routine exit
|
||||
*
|
||||
* @param interruptType The interrupt routine handle name
|
||||
* @param program The program
|
||||
* @return the fragment instance spec factory
|
||||
*/
|
||||
public static AsmFragmentInstanceSpecBuilder interruptExit(String interruptType, Program program) {
|
||||
Map<String, Value> bindings = new HashMap<>();
|
||||
String signature = "isr_" + interruptType + "_exit";
|
||||
ScopeRef codeScope = program.getScope().getRef();
|
||||
final AsmFragmentInstanceSpec fragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
|
||||
return new AsmFragmentInstanceSpecBuilder(program, bindings, fragmentInstanceSpec);
|
||||
}
|
||||
|
||||
private AsmFragmentInstanceSpecBuilder(Program program, Map<String, Value> bindings, AsmFragmentInstanceSpec asmFragmentInstanceSpec) {
|
||||
this.program = program;
|
||||
this.bindings = bindings;
|
||||
this.asmFragmentInstanceSpec = asmFragmentInstanceSpec;
|
||||
}
|
||||
|
||||
|
||||
public static AsmFragmentInstanceSpecBuilder conditionalJump(StatementConditionalJump conditionalJump, ControlFlowBlock block, Program program) {
|
||||
return new AsmFragmentInstanceSpecBuilder(conditionalJump, block, program);
|
||||
}
|
||||
|
||||
private AsmFragmentInstanceSpecBuilder(
|
||||
StatementConditionalJump conditionalJump,
|
||||
ControlFlowBlock block,
|
||||
Program program,
|
||||
ControlFlowGraph graph) {
|
||||
Program program) {
|
||||
this.program = program;
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
ScopeRef codeScope = program.getStatementInfos().getBlock(conditionalJump).getScope();
|
||||
String signature = conditionalJumpSignature(conditionalJump, block, graph);
|
||||
String signature = conditionalJumpSignature(conditionalJump, block, program.getGraph());
|
||||
this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
|
||||
}
|
||||
|
||||
public AsmFragmentInstanceSpecFactory(StatementExprSideEffect exprSideEffect, Program program) {
|
||||
public static AsmFragmentInstanceSpecBuilder exprSideEffect(StatementExprSideEffect exprSideEffect, Program program) {
|
||||
return new AsmFragmentInstanceSpecBuilder(exprSideEffect, program);
|
||||
}
|
||||
|
||||
private AsmFragmentInstanceSpecBuilder(StatementExprSideEffect exprSideEffect, Program program) {
|
||||
this.program = program;
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
ScopeRef codeScope = program.getStatementInfos().getBlock(exprSideEffect).getScope();
|
||||
@ -69,7 +124,11 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
|
||||
}
|
||||
|
||||
public AsmFragmentInstanceSpecFactory(StatementAssignment assignment, Program program) {
|
||||
public static AsmFragmentInstanceSpecBuilder assignment(StatementAssignment assignment, Program program) {
|
||||
return new AsmFragmentInstanceSpecBuilder(assignment, program);
|
||||
}
|
||||
|
||||
private AsmFragmentInstanceSpecBuilder(StatementAssignment assignment, Program program) {
|
||||
this.program = program;
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
ScopeRef codeScope = program.getStatementInfos().getBlock(assignment).getScope();
|
||||
@ -81,14 +140,22 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
|
||||
}
|
||||
|
||||
public AsmFragmentInstanceSpecFactory(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) {
|
||||
public static AsmFragmentInstanceSpecBuilder assignment(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) {
|
||||
return new AsmFragmentInstanceSpecBuilder(lValue, rValue, program, codeScopeRef);
|
||||
}
|
||||
|
||||
private AsmFragmentInstanceSpecBuilder(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) {
|
||||
this.program = program;
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
String signature = assignmentSignature(lValue, null, null, rValue);
|
||||
this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScopeRef);
|
||||
}
|
||||
|
||||
public AsmFragmentInstanceSpecFactory(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) {
|
||||
public static AsmFragmentInstanceSpecBuilder assignmentAlu(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) {
|
||||
return new AsmFragmentInstanceSpecBuilder(assignment, assignmentAlu, program);
|
||||
}
|
||||
|
||||
private AsmFragmentInstanceSpecBuilder(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) {
|
||||
this.program = program;
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
ScopeRef codeScope = program.getStatementInfos().getBlock(assignment).getScope();
|
||||
@ -96,6 +163,10 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope);
|
||||
}
|
||||
|
||||
public Map<String, Value> getBindings() {
|
||||
return bindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the created ASM fragment instance specification
|
||||
*
|
||||
@ -495,7 +566,7 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
if(Registers.RegisterType.ZP_MEM.equals(register.getType())) {
|
||||
// Examine if the ZP register is already bound
|
||||
Registers.RegisterZpMem registerZp = (Registers.RegisterZpMem) register;
|
||||
String zpNameIdx = null;
|
||||
String memNameIdx = null;
|
||||
for(String boundName : bindings.keySet()) {
|
||||
Value boundValue = bindings.get(boundName);
|
||||
if(boundValue instanceof Variable && ((Variable) boundValue).isVariable()) {
|
||||
@ -505,17 +576,17 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
Registers.RegisterZpMem boundRegisterZp = (Registers.RegisterZpMem) boundRegister;
|
||||
if(registerZp.getZp() == boundRegisterZp.getZp()) {
|
||||
// Found other register with same ZP address!
|
||||
zpNameIdx = boundName.substring(boundName.length() - 1);
|
||||
memNameIdx = boundName.substring(boundName.length() - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If not create a new one
|
||||
if(zpNameIdx == null) {
|
||||
zpNameIdx = Integer.toString(nextZpIdx++);
|
||||
if(memNameIdx == null) {
|
||||
memNameIdx = Integer.toString(nextMemIdx++);
|
||||
}
|
||||
return "z" + zpNameIdx;
|
||||
return "z" + memNameIdx;
|
||||
} else if(Registers.RegisterType.MAIN_MEM.equals(register.getType())) {
|
||||
String memNameIdx = null;
|
||||
for(String boundName : bindings.keySet()) {
|
||||
@ -532,7 +603,7 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
}
|
||||
}
|
||||
if(memNameIdx == null) {
|
||||
memNameIdx = Integer.toString(nextZpIdx++);
|
||||
memNameIdx = Integer.toString(nextMemIdx++);
|
||||
}
|
||||
return "m" + memNameIdx;
|
||||
} else if(Registers.RegisterType.REG_A.equals(register.getType())) {
|
||||
@ -564,5 +635,4 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
return "c" + nextConstIdx++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -111,8 +111,8 @@ public class AsmFragmentTemplateSynthesizer {
|
||||
double minScore = Double.MAX_VALUE;
|
||||
for(AsmFragmentTemplate candidateTemplate : candidates) {
|
||||
double score = candidateTemplate.getCycles();
|
||||
if(candidateTemplate.getClobber().isClobberZ()) score += 0.25;
|
||||
if(candidateTemplate.getClobber().isClobberA()) score += 0.5;
|
||||
if(candidateTemplate.getClobber().isClobberZ()) score += 1.0;
|
||||
if(candidateTemplate.getClobber().isClobberY()) score += 1.0;
|
||||
if(candidateTemplate.getClobber().isClobberX()) score += 1.5;
|
||||
if(score < minScore) {
|
||||
@ -531,7 +531,6 @@ public class AsmFragmentTemplateSynthesizer {
|
||||
} else {
|
||||
CharStream fragmentCharStream = CharStreams.fromStream(fragmentStream);
|
||||
body = fixNewlines(fragmentCharStream.toString());
|
||||
|
||||
}
|
||||
return new AsmFragmentTemplate(signature, body, targetCpu, false);
|
||||
} catch(IOException e) {
|
||||
|
@ -103,10 +103,10 @@ public class Directive {
|
||||
|
||||
/** Function declared interrupt. */
|
||||
public static class Interrupt extends Directive {
|
||||
public Procedure.InterruptType interruptType;
|
||||
public String interruptType;
|
||||
|
||||
public Interrupt(Procedure.InterruptType interruptType) {
|
||||
super(interruptType.name());
|
||||
public Interrupt(String interruptType) {
|
||||
super(interruptType);
|
||||
this.interruptType = interruptType;
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,9 @@ public class TargetPlatform {
|
||||
|
||||
/** Configuration for the variable builder. */
|
||||
private VariableBuilderConfig variableBuilderConfig;
|
||||
|
||||
/** Default interrupt type. */
|
||||
private String interruptType = "hardware_all";
|
||||
|
||||
public TargetPlatform(String name) {
|
||||
this.name = name;
|
||||
@ -151,4 +154,11 @@ public class TargetPlatform {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public void setInterruptType(String interruptType) {
|
||||
this.interruptType = interruptType;
|
||||
}
|
||||
|
||||
public String getInterruptType() {
|
||||
return interruptType;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class Procedure extends Scope {
|
||||
/** True if the procedure is declared intrinsic. */
|
||||
private boolean declaredIntrinsic;
|
||||
/** The type of interrupt that the procedure serves. Null for all procedures not serving an interrupt. */
|
||||
private InterruptType interruptType;
|
||||
private String interruptType;
|
||||
/** Comments preceding the procedure in the source code. */
|
||||
private List<Comment> comments;
|
||||
/** Reserved zeropage addresses. */
|
||||
@ -176,11 +176,11 @@ public class Procedure extends Scope {
|
||||
this.declaredInline = declaredInline;
|
||||
}
|
||||
|
||||
public InterruptType getInterruptType() {
|
||||
public String getInterruptType() {
|
||||
return interruptType;
|
||||
}
|
||||
|
||||
public void setInterruptType(InterruptType interruptType) {
|
||||
public void setInterruptType(String interruptType) {
|
||||
this.interruptType = interruptType;
|
||||
}
|
||||
|
||||
@ -218,26 +218,6 @@ public class Procedure extends Scope {
|
||||
isConstructor = constructor;
|
||||
}
|
||||
|
||||
/** The different types of supported interrupts. */
|
||||
public enum InterruptType {
|
||||
/** Interrupt served by the kernel called through $0314-5. Will exit through the kernel using $ea31. */
|
||||
KERNEL_KEYBOARD,
|
||||
/** Interrupt served by the kernel called through $0314-5. Will exit through the kernel using $ea81. */
|
||||
KERNEL_MIN,
|
||||
/** Interrupt served directly from hardware through $fffe-f. Will exit through RTI and will save NO registers. */
|
||||
HARDWARE_NONE,
|
||||
/** Interrupt served directly from hardware through $fffe-f. Will exit through RTI and will save ALL registers. */
|
||||
HARDWARE_ALL,
|
||||
/** Interrupt served directly from hardware through $fffe-f. Will exit through RTI and will save ALL registers using the stack. */
|
||||
HARDWARE_STACK,
|
||||
/** Interrupt served directly from hardware through $fffe-f. Will exit through RTI and will save necessary registers based on clobber. */
|
||||
HARDWARE_CLOBBER;
|
||||
|
||||
/** The default interrupt type if none is explicitly declared (KERNEL_MIN). */
|
||||
public static InterruptType DEFAULT = InterruptType.KERNEL_MIN;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(null);
|
||||
@ -256,7 +236,7 @@ public class Procedure extends Scope {
|
||||
res.append(getCallingConvention().getName()).append(" ");
|
||||
}
|
||||
if(interruptType != null) {
|
||||
res.append("interrupt(").append(interruptType).append(") ");
|
||||
res.append("__interrupt(").append(interruptType).append(") ");
|
||||
}
|
||||
res.append(returnType.getTypeName()).append(" ").append(getFullName()).append("(");
|
||||
boolean first = true;
|
||||
@ -287,7 +267,7 @@ public class Procedure extends Scope {
|
||||
return declaredInline == procedure.declaredInline &&
|
||||
Objects.equals(returnType, procedure.returnType) &&
|
||||
Objects.equals(parameterNames, procedure.parameterNames) &&
|
||||
interruptType == procedure.interruptType &&
|
||||
Objects.equals(interruptType, procedure.interruptType) &&
|
||||
Objects.equals(comments, procedure.comments) &&
|
||||
Objects.equals(reservedZps, procedure.reservedZps) &&
|
||||
Objects.equals(codeSegment, procedure.codeSegment) &&
|
||||
|
@ -43,6 +43,7 @@ public class CParser {
|
||||
public static final String PRAGMA_CALLING = "calling";
|
||||
public static final String PRAGMA_ZP_RESERVE = "zp_reserve";
|
||||
public static final String PRAGMA_CONSTRUCTOR_FOR = "constructor_for";
|
||||
public static final String PRAGMA_INTERRUPT = "interrupt";
|
||||
|
||||
/** The Program. */
|
||||
private Program program;
|
||||
|
@ -33,6 +33,11 @@ public class CTargetPlatformParser {
|
||||
final JsonReader jsonReader = Json.createReader(new BufferedInputStream(new FileInputStream(platformFile)));
|
||||
final JsonObject platformJson = jsonReader.readObject();
|
||||
TargetPlatform targetPlatform = new TargetPlatform(platformName);
|
||||
{
|
||||
final String interruptType = platformJson.getString("interrupt", null);
|
||||
if(interruptType != null)
|
||||
targetPlatform.setInterruptType(interruptType);
|
||||
}
|
||||
{
|
||||
final String cpuName = platformJson.getString("cpu", null);
|
||||
if(cpuName != null)
|
||||
|
@ -69,7 +69,7 @@ ALIGN: 'align' ;
|
||||
INLINE: 'inline' ;
|
||||
VOLATILE: 'volatile' ;
|
||||
STATIC: 'static' ;
|
||||
INTERRUPT: 'interrupt' ;
|
||||
INTERRUPT: '__interrupt' ;
|
||||
REGISTER: 'register' ;
|
||||
LOCAL_RESERVE: '__zp_reserve' ;
|
||||
ADDRESS: '__address' ;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -178,7 +178,7 @@ IMPORT_COMMENT_BLOCK=153
|
||||
'inline'=44
|
||||
'volatile'=45
|
||||
'static'=46
|
||||
'interrupt'=47
|
||||
'__interrupt'=47
|
||||
'register'=48
|
||||
'__zp_reserve'=49
|
||||
'__address'=50
|
||||
|
@ -46,7 +46,7 @@ null
|
||||
'inline'
|
||||
'volatile'
|
||||
'static'
|
||||
'interrupt'
|
||||
'__interrupt'
|
||||
'register'
|
||||
'__zp_reserve'
|
||||
'__address'
|
||||
|
@ -84,7 +84,7 @@ public class KickCParser extends Parser {
|
||||
"'--'", "'&'", "'~'", "'^'", "'|'", null, null, "'=='", "'!='", null,
|
||||
"'<='", "'>='", null, "'&&'", "'||'", "'='", null, "'typedef'", "'const'",
|
||||
"'extern'", "'export'", "'align'", "'inline'", "'volatile'", "'static'",
|
||||
"'interrupt'", "'register'", "'__zp_reserve'", "'__address'", "'__zp'",
|
||||
"'__interrupt'", "'register'", "'__zp_reserve'", "'__address'", "'__zp'",
|
||||
"'__mem'", "'__ssa'", "'__ma'", "'__intrinsic'", null, "'if'", "'else'",
|
||||
"'while'", "'do'", "'for'", "'switch'", "'return'", "'break'", "'continue'",
|
||||
"'asm'", "'default'", "'case'", "'struct'", "'enum'", "'sizeof'", "'typeid'",
|
||||
|
@ -178,7 +178,7 @@ IMPORT_COMMENT_BLOCK=153
|
||||
'inline'=44
|
||||
'volatile'=45
|
||||
'static'=46
|
||||
'interrupt'=47
|
||||
'__interrupt'=47
|
||||
'register'=48
|
||||
'__zp_reserve'=49
|
||||
'__address'=50
|
||||
|
@ -34,27 +34,26 @@ import java.util.stream.Collectors;
|
||||
public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Object> {
|
||||
|
||||
/** The C parser keeping track of C-files and lexers */
|
||||
private CParser cParser;
|
||||
private final CParser cParser;
|
||||
/** The source ANTLR parse tree of the source file. */
|
||||
private KickCParser.FileContext fileCtx;
|
||||
private final KickCParser.FileContext fileCtx;
|
||||
/** The program containing all compile structures. */
|
||||
private Program program;
|
||||
private final Program program;
|
||||
/** Used to build the scopes of the source file. */
|
||||
private Stack<Scope> scopeStack;
|
||||
/** The memory area used by default for variables. */
|
||||
private Variable.MemoryArea defaultMemoryArea;
|
||||
private final Stack<Scope> scopeStack;
|
||||
/** All #pragma constructor_for() statements. Collected during parsing and handled by {@link #generate()} before returning. */
|
||||
private List<KickCParser.PragmaContext> pragmaConstructorFors;
|
||||
private final List<KickCParser.PragmaContext> pragmaConstructorFors;
|
||||
|
||||
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program, Procedure.CallingConvention initialCallingConvention, StringEncoding defaultEncoding) {
|
||||
|
||||
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program, Procedure.CallingConvention initialCallingConvention, StringEncoding defaultEncoding, String defaultInterruptType) {
|
||||
this.cParser = cParser;
|
||||
this.fileCtx = fileCtx;
|
||||
this.program = program;
|
||||
this.scopeStack = new Stack<>();
|
||||
this.defaultMemoryArea = Variable.MemoryArea.ZEROPAGE_MEMORY;
|
||||
this.currentCallingConvention = initialCallingConvention;
|
||||
this.currentEncoding = defaultEncoding;
|
||||
this.pragmaConstructorFors = new ArrayList();
|
||||
this.currentInterruptType = defaultInterruptType;
|
||||
scopeStack.push(program.getScope());
|
||||
}
|
||||
|
||||
@ -250,6 +249,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
case CParser.PRAGMA_CALLING:
|
||||
currentCallingConvention = pragmaParamCallingConvention(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_INTERRUPT:
|
||||
this.currentInterruptType = pragmaParamName(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_ZP_RESERVE:
|
||||
List<Integer> reservedZps = pragmaParamRanges(ctx.pragmaParam());
|
||||
program.addReservedZps(reservedZps);
|
||||
@ -372,12 +374,15 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
/** The current calling convention for procedures. */
|
||||
private Procedure.CallingConvention currentCallingConvention;
|
||||
|
||||
/** The current code segment - if null the default segment is used. */
|
||||
/** The current code segment. */
|
||||
private String currentCodeSegment = Scope.SEGMENT_CODE_DEFAULT;
|
||||
|
||||
/** The current data segment - if null the default segment is used. */
|
||||
/** The current data segment. */
|
||||
private String currentDataSegment = Scope.SEGMENT_DATA_DEFAULT;
|
||||
|
||||
/** The current default interrupt type. */
|
||||
private String currentInterruptType;
|
||||
|
||||
@Override
|
||||
public Object visitDeclFunction(KickCParser.DeclFunctionContext ctx) {
|
||||
this.visit(ctx.declType());
|
||||
@ -1215,13 +1220,11 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
public Object visitDirectiveInterrupt(KickCParser.DirectiveInterruptContext ctx) {
|
||||
String interruptType;
|
||||
if(ctx.getChildCount() > 1) {
|
||||
interruptType = ctx.getChild(2).getText().toUpperCase(Locale.ENGLISH);
|
||||
interruptType = ctx.getChild(2).getText().toLowerCase(Locale.ENGLISH);
|
||||
} else {
|
||||
// The default interrupt type
|
||||
interruptType = Procedure.InterruptType.DEFAULT.name();
|
||||
interruptType = currentInterruptType;
|
||||
}
|
||||
Procedure.InterruptType type = Procedure.InterruptType.valueOf(interruptType);
|
||||
return new Directive.Interrupt(type);
|
||||
return new Directive.Interrupt(interruptType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1435,7 +1438,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
/** The loops being generated. */
|
||||
private Stack<Loop> loopStack = new Stack<>();
|
||||
private final Stack<Loop> loopStack = new Stack<>();
|
||||
|
||||
@Override
|
||||
public Void visitStmtWhile(KickCParser.StmtWhileContext ctx) {
|
||||
|
@ -32,14 +32,14 @@ public class Pass4CodeGeneration {
|
||||
boolean warnFragmentMissing;
|
||||
|
||||
/** The program being generated. */
|
||||
private Program program;
|
||||
private final Program program;
|
||||
|
||||
/**
|
||||
* Keeps track of the phi transitions into blocks during code generation.
|
||||
* Used to ensure that duplicate transitions are only code generated once.
|
||||
* Maps to-blocks to the transition information for the block
|
||||
*/
|
||||
private Map<PhiTransitions.PhiTransition, Boolean> transitionsGenerated = new LinkedHashMap<>();
|
||||
private final Map<PhiTransitions.PhiTransition, Boolean> transitionsGenerated = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Determines if a phi-transition has already been code-generated
|
||||
@ -97,7 +97,7 @@ public class Pass4CodeGeneration {
|
||||
String entryName = program.getStartProcedure().getFullName();
|
||||
linkScriptBody = linkScriptBody.replace("%E", entryName);
|
||||
Number startAddress = program.getTargetPlatform().getStartAddress();
|
||||
if(startAddress!=null)
|
||||
if(startAddress != null)
|
||||
linkScriptBody = linkScriptBody.replace("%P", AsmFormat.getAsmNumber(startAddress));
|
||||
asm.addLine(new AsmInlineKickAsm(linkScriptBody, 0L, 0L));
|
||||
|
||||
@ -181,7 +181,7 @@ public class Pass4CodeGeneration {
|
||||
// Name of the current data segment
|
||||
private String currentCodeSegmentName = Scope.SEGMENT_CODE_DEFAULT;
|
||||
// Name of the current code segment
|
||||
private String currentDataSegmentName = Scope.SEGMENT_DATA_DEFAULT;
|
||||
private final String currentDataSegmentName = Scope.SEGMENT_DATA_DEFAULT;
|
||||
// Name of the current active segment
|
||||
private String currentSegmentName = "";
|
||||
|
||||
@ -751,13 +751,13 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
}
|
||||
} else if(value instanceof ConstantString) {
|
||||
ConstantString stringValue = (ConstantString) value;
|
||||
// Ensure encoding is good
|
||||
String asmConstant = AsmFormat.getAsmConstant(program, stringValue, 99, scopeRef);
|
||||
dataChunk.addDataString(asmConstant, getEncoding(stringValue));
|
||||
if(stringValue.isZeroTerminated()) {
|
||||
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null);
|
||||
}
|
||||
ConstantString stringValue = (ConstantString) value;
|
||||
// Ensure encoding is good
|
||||
String asmConstant = AsmFormat.getAsmConstant(program, stringValue, 99, scopeRef);
|
||||
dataChunk.addDataString(asmConstant, getEncoding(stringValue));
|
||||
if(stringValue.isZeroTerminated()) {
|
||||
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null);
|
||||
}
|
||||
} else if(SymbolType.BYTE.equals(valueType) || SymbolType.SBYTE.equals(valueType)) {
|
||||
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, AsmFormat.getAsmConstant(program, value, 99, scopeRef), getEncoding(value));
|
||||
} else if(SymbolType.WORD.equals(valueType) || SymbolType.SWORD.equals(valueType)) {
|
||||
@ -838,9 +838,9 @@ public class Pass4CodeGeneration {
|
||||
throw new AsmFragmentInstance.AluNotApplicableException();
|
||||
}
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(assignment, assignmentAlu, program);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.assignmentAlu(assignment, assignmentAlu, program);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecBuilder);
|
||||
generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec());
|
||||
aluState.clear();
|
||||
return;
|
||||
}
|
||||
@ -855,8 +855,7 @@ public class Pass4CodeGeneration {
|
||||
Registers.Register lValRegister = program.getSymbolInfos().getVariable(lValueRef).getAllocation();
|
||||
if(lValRegister.getType().equals(Registers.RegisterType.REG_ALU)) {
|
||||
//asm.addComment(statement + " // ALU");
|
||||
StatementAssignment assignmentAlu = assignment;
|
||||
aluState.setAluAssignment(assignmentAlu);
|
||||
aluState.setAluAssignment(assignment);
|
||||
isAlu = true;
|
||||
}
|
||||
}
|
||||
@ -864,15 +863,15 @@ public class Pass4CodeGeneration {
|
||||
if(assignment.getOperator() == null && assignment.getrValue1() == null && isRegisterCopy(lValue, assignment.getrValue2())) {
|
||||
//asm.addComment(lValue.toString(program) + " = " + assignment.getrValue2().toString(program) + " // register copy " + getRegister(lValue));
|
||||
} else {
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(assignment, program);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.assignment(assignment, program);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecBuilder);
|
||||
generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec());
|
||||
}
|
||||
}
|
||||
} else if(statement instanceof StatementConditionalJump) {
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory((StatementConditionalJump) statement, block, program, getGraph());
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.conditionalJump((StatementConditionalJump) statement, block, program);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecBuilder);
|
||||
generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec());
|
||||
} else if(statement instanceof StatementCall) {
|
||||
StatementCall call = (StatementCall) statement;
|
||||
Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
@ -895,9 +894,9 @@ public class Pass4CodeGeneration {
|
||||
asm.getCurrentChunk().setFragment("jsr");
|
||||
asm.addInstruction("jsr", CpuAddressingMode.ABS, call.getProcedure().getFullName(), false);
|
||||
} else if(statement instanceof StatementExprSideEffect) {
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory((StatementExprSideEffect) statement, program);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.exprSideEffect((StatementExprSideEffect) statement, program);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecBuilder);
|
||||
generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec());
|
||||
} else if(statement instanceof StatementReturn) {
|
||||
Procedure procedure = null;
|
||||
ScopeRef scope = block.getScope();
|
||||
@ -907,7 +906,7 @@ public class Pass4CodeGeneration {
|
||||
if(procedure == null || procedure.getInterruptType() == null) {
|
||||
asm.addInstruction("rts", CpuAddressingMode.NON, null, false);
|
||||
} else {
|
||||
generateInterruptExit(asm, statement, procedure.getInterruptType());
|
||||
generateInterruptExit(asm, procedure);
|
||||
}
|
||||
} else if(statement instanceof StatementAsm) {
|
||||
StatementAsm statementAsm = (StatementAsm) statement;
|
||||
@ -1025,30 +1024,21 @@ public class Pass4CodeGeneration {
|
||||
* @param procedure The interrupt procedure
|
||||
*/
|
||||
private void generateInterruptEntry(AsmProgram asm, Procedure procedure) {
|
||||
Procedure.InterruptType interruptType = procedure.getInterruptType();
|
||||
asm.startChunk(procedure.getRef(), null, "entry interrupt(" + interruptType.name() + ")");
|
||||
if(Procedure.InterruptType.KERNEL_MIN.equals(interruptType)) {
|
||||
// No entry ASM needed
|
||||
} else if(Procedure.InterruptType.KERNEL_KEYBOARD.equals(interruptType)) {
|
||||
// No entry ASM needed
|
||||
} else if(Procedure.InterruptType.HARDWARE_ALL.equals(interruptType)) {
|
||||
asm.addInstruction("sta", CpuAddressingMode.ABS, "rega+1", false).setDontOptimize(true);
|
||||
asm.addInstruction("stx", CpuAddressingMode.ABS, "regx+1", false).setDontOptimize(true);
|
||||
asm.addInstruction("sty", CpuAddressingMode.ABS, "regy+1", false).setDontOptimize(true);
|
||||
} else if(Procedure.InterruptType.HARDWARE_STACK.equals(interruptType)) {
|
||||
asm.addInstruction("pha", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("txa", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("pha", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("tya", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("pha", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
} else if(Procedure.InterruptType.HARDWARE_NONE.equals(interruptType)) {
|
||||
// No entry ASM needed
|
||||
} else if(Procedure.InterruptType.HARDWARE_CLOBBER.equals(interruptType)) {
|
||||
asm.addInstruction("sta", CpuAddressingMode.ABS, "rega+1", false).setDontOptimize(true);
|
||||
asm.addInstruction("stx", CpuAddressingMode.ABS, "regx+1", false).setDontOptimize(true);
|
||||
asm.addInstruction("sty", CpuAddressingMode.ABS, "regy+1", false).setDontOptimize(true);
|
||||
final String interruptType = procedure.getInterruptType().toLowerCase();
|
||||
AsmFragmentInstanceSpecBuilder entryFragment;
|
||||
String entryName;
|
||||
if(interruptType.contains("clobber")) {
|
||||
entryFragment = AsmFragmentInstanceSpecBuilder.interruptEntry(interruptType.replace("clobber", "all"), program);
|
||||
entryName = entryFragment.getAsmFragmentInstanceSpec().getSignature().replace("all", "clobber");
|
||||
} else {
|
||||
throw new RuntimeException("Interrupt Type not supported " + interruptType.name());
|
||||
entryFragment = AsmFragmentInstanceSpecBuilder.interruptEntry(interruptType, program);
|
||||
entryName = entryFragment.getAsmFragmentInstanceSpec().getSignature();
|
||||
}
|
||||
try {
|
||||
asm.startChunk(procedure.getRef(), null, "interrupt(" + entryName+ ")");
|
||||
generateAsm(asm, entryFragment.getAsmFragmentInstanceSpec());
|
||||
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
|
||||
throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure.toString() + "\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1056,42 +1046,28 @@ public class Pass4CodeGeneration {
|
||||
* Generate exit-code for ending an interrupt procedure based on the interrupt type
|
||||
*
|
||||
* @param asm The assembler to generate code into
|
||||
* @param statement The return statement
|
||||
* @param interruptType The type of interrupt to generate
|
||||
* @param procedure The procedure
|
||||
*/
|
||||
private void generateInterruptExit(AsmProgram asm, Statement statement, Procedure.InterruptType interruptType) {
|
||||
asm.getCurrentChunk().setSource(asm.getCurrentChunk().getSource() + " - exit interrupt(" + interruptType.name() + ")");
|
||||
if(Procedure.InterruptType.KERNEL_MIN.equals(interruptType)) {
|
||||
asm.addInstruction("jmp", CpuAddressingMode.ABS, "$ea81", false);
|
||||
} else if(Procedure.InterruptType.KERNEL_KEYBOARD.equals(interruptType)) {
|
||||
asm.addInstruction("jmp", CpuAddressingMode.ABS, "$ea31", false);
|
||||
} else if(Procedure.InterruptType.HARDWARE_ALL.equals(interruptType)) {
|
||||
asm.addLabel("rega").setDontOptimize(true);
|
||||
asm.addInstruction("lda", CpuAddressingMode.IMM, "00", false).setDontOptimize(true);
|
||||
asm.addLabel("regx").setDontOptimize(true);
|
||||
asm.addInstruction("ldx", CpuAddressingMode.IMM, "00", false).setDontOptimize(true);
|
||||
asm.addLabel("regy").setDontOptimize(true);
|
||||
asm.addInstruction("ldy", CpuAddressingMode.IMM, "00", false).setDontOptimize(true);
|
||||
asm.addInstruction("rti", CpuAddressingMode.NON, null, false);
|
||||
} else if(Procedure.InterruptType.HARDWARE_STACK.equals(interruptType)) {
|
||||
asm.addInstruction("pla", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("tay", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("pla", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("tax", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("pla", CpuAddressingMode.NON, null, false).setDontOptimize(true);
|
||||
asm.addInstruction("rti", CpuAddressingMode.NON, null, false);
|
||||
} else if(Procedure.InterruptType.HARDWARE_NONE.equals(interruptType)) {
|
||||
asm.addInstruction("rti", CpuAddressingMode.NON, null, false);
|
||||
} else if(Procedure.InterruptType.HARDWARE_CLOBBER.equals(interruptType)) {
|
||||
asm.addLabel("rega").setDontOptimize(true);
|
||||
asm.addInstruction("lda", CpuAddressingMode.IMM, "00", false).setDontOptimize(true);
|
||||
asm.addLabel("regx").setDontOptimize(true);
|
||||
asm.addInstruction("ldx", CpuAddressingMode.IMM, "00", false).setDontOptimize(true);
|
||||
asm.addLabel("regy").setDontOptimize(true);
|
||||
asm.addInstruction("ldy", CpuAddressingMode.IMM, "00", false).setDontOptimize(true);
|
||||
asm.addInstruction("rti", CpuAddressingMode.NON, null, false);
|
||||
private void generateInterruptExit(AsmProgram asm, Procedure procedure) {
|
||||
final String interruptType = procedure.getInterruptType().toLowerCase();
|
||||
AsmFragmentInstanceSpecBuilder entryFragment;
|
||||
String entryName;
|
||||
if(interruptType.contains("clobber")) {
|
||||
entryFragment = AsmFragmentInstanceSpecBuilder.interruptExit(interruptType.replace("clobber", "all"), program);
|
||||
entryName = entryFragment.getAsmFragmentInstanceSpec().getSignature().replace("all", "clobber");
|
||||
} else {
|
||||
throw new RuntimeException("Interrupt Type not supported " + statement);
|
||||
entryFragment = AsmFragmentInstanceSpecBuilder.interruptExit(interruptType, program);
|
||||
entryName = entryFragment.getAsmFragmentInstanceSpec().getSignature();
|
||||
}
|
||||
asm.startChunk(procedure.getRef(), null, "interrupt(" + entryName + ")");
|
||||
try {
|
||||
generateAsm(asm, entryFragment.getAsmFragmentInstanceSpec());
|
||||
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
|
||||
throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure.toString() + "\n" + e.getMessage());
|
||||
}
|
||||
// Mark labels as don't optimize
|
||||
for(AsmLine asmLine : asm.getCurrentChunk().getLines()) {
|
||||
if(asmLine instanceof AsmLabel) ((AsmLabel) asmLine).setDontOptimize(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1168,9 +1144,9 @@ public class Pass4CodeGeneration {
|
||||
if(isRegisterCopy(lValue, rValue)) {
|
||||
asm.getCurrentChunk().setFragment("register_copy");
|
||||
} else {
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(lValue, rValue, program, scope);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.assignment(lValue, rValue, program, scope);
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecBuilder);
|
||||
generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec());
|
||||
}
|
||||
}
|
||||
transitionSetGenerated(transition);
|
||||
@ -1186,7 +1162,7 @@ public class Pass4CodeGeneration {
|
||||
* @param asm The ASM program (where any .encoding directive will be emitted)
|
||||
* @param asmFragmentInstance The ASM fragment to be emitted
|
||||
*/
|
||||
private static void ensureEncoding(AsmProgram asm, AsmFragmentInstanceSpecFactory asmFragmentInstance) {
|
||||
private static void ensureEncoding(AsmProgram asm, AsmFragmentInstanceSpecBuilder asmFragmentInstance) {
|
||||
asm.ensureEncoding(getEncoding(asmFragmentInstance));
|
||||
}
|
||||
|
||||
@ -1222,7 +1198,7 @@ public class Pass4CodeGeneration {
|
||||
* @param asmFragmentInstance The asm fragment instance to examine
|
||||
* @return Any encoding found inside the constant
|
||||
*/
|
||||
private static Set<StringEncoding> getEncoding(AsmFragmentInstanceSpecFactory asmFragmentInstance) {
|
||||
private static Set<StringEncoding> getEncoding(AsmFragmentInstanceSpecBuilder asmFragmentInstance) {
|
||||
LinkedHashSet<StringEncoding> encodings = new LinkedHashSet<>();
|
||||
Map<String, Value> bindings = asmFragmentInstance.getBindings();
|
||||
for(Value boundValue : bindings.values()) {
|
||||
|
@ -1,21 +1,20 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.asm.AsmChunk;
|
||||
import dk.camelot64.cpufamily6502.CpuClobber;
|
||||
import dk.camelot64.kickc.asm.AsmLine;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.asm.*;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentInstance;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentInstanceSpecBuilder;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||
import dk.camelot64.kickc.model.CallGraph;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
/*** Ensure that all interrupt procedures with type {@link Procedure.InterruptType#HARDWARE_CLOBBER } only saves the necessary registers. */
|
||||
/*** Ensure that all interrupt procedures with CLOBBER type only saves the necessary registers. */
|
||||
public class Pass4InterruptClobberFix extends Pass2Base {
|
||||
|
||||
public Pass4InterruptClobberFix(Program program) {
|
||||
@ -28,44 +27,38 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
||||
public void fix() {
|
||||
Collection<Procedure> procedures = getProgram().getScope().getAllProcedures(true);
|
||||
for(Procedure procedure : procedures) {
|
||||
if(Procedure.InterruptType.HARDWARE_CLOBBER.equals(procedure.getInterruptType())) {
|
||||
|
||||
if(procedure.getInterruptType() != null && procedure.getInterruptType().toLowerCase().contains("clobber")) {
|
||||
// Find the interrupt routine clobber
|
||||
CpuClobber procClobber = getProcedureClobber(procedure);
|
||||
getLog().append("Interrupt procedure "+procedure.getFullName()+" clobbers "+procClobber.toString());
|
||||
|
||||
getLog().append("Interrupt procedure " + procedure.getFullName() + " clobbers " + procClobber.toString());
|
||||
// Find the entry/exit blocks for the interrupt
|
||||
AsmChunk interruptEntry = null;
|
||||
AsmChunk interruptExit = null;
|
||||
for(AsmChunk asmChunk : getProgram().getAsm().getChunks()) {
|
||||
if(procedure.getFullName().equals(asmChunk.getScopeLabel())) {
|
||||
if(asmChunk.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
|
||||
if(asmChunk.getSource().contains("entry interrupt")) {
|
||||
if(asmChunk.getSource().contains("clobber")) {
|
||||
if(asmChunk.getSource().endsWith("_entry)")) {
|
||||
interruptEntry = asmChunk;
|
||||
} else if(asmChunk.getSource().contains("exit interrupt")) {
|
||||
} else if(asmChunk.getSource().endsWith("_exit)")) {
|
||||
interruptExit = asmChunk;
|
||||
} else {
|
||||
throw new RuntimeException("Unknown interrupt ASM chunk "+ asmChunk.getSource());
|
||||
throw new RuntimeException("Unknown interrupt ASM chunk " + asmChunk.getSource());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(interruptEntry==null || interruptExit==null) {
|
||||
throw new RuntimeException("Cannot find interrupt entry/exit for interrupt "+procedure.getFullName());
|
||||
if(interruptEntry == null || interruptExit == null) {
|
||||
throw new RuntimeException("Cannot find interrupt entry/exit for interrupt " + procedure.getFullName());
|
||||
}
|
||||
List<String> notClobberedRegisters = getNonClobberedRegisterNames(procClobber);
|
||||
if(notClobberedRegisters.isEmpty()) {
|
||||
// All registers clobbered - no need to fix anything
|
||||
continue;
|
||||
}
|
||||
// Remove all lines saving/restoring non-clobbered registers in entry
|
||||
pruneNonClobberedInterruptLines(interruptEntry, notClobberedRegisters);
|
||||
// Remove all lines saving/restoring non-clobbered registers in entry
|
||||
pruneNonClobberedInterruptLines(interruptExit, notClobberedRegisters);
|
||||
|
||||
String clobberedRegisters = getClobberedRegisterNames(procClobber);
|
||||
// Update the interrupt entry ASM with the proper clobber fragment
|
||||
updateClobberFragment(interruptEntry, clobberedRegisters);
|
||||
// Update the interrupt exit ASM with the proper clobber fragment
|
||||
updateClobberFragment(interruptExit, clobberedRegisters);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CpuClobber getProcedureClobber(Procedure procedure) {
|
||||
@ -73,7 +66,7 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
||||
CpuClobber procClobber = CpuClobber.CLOBBER_NONE;
|
||||
for(AsmChunk asmChunk : asm.getChunks()) {
|
||||
if(procedure.getFullName().equals(asmChunk.getScopeLabel())) {
|
||||
if(asmChunk.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
|
||||
if(asmChunk.getSource().contains("clobber")) {
|
||||
// Do not count clobber in the entry/exit
|
||||
continue;
|
||||
}
|
||||
@ -96,33 +89,76 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
||||
return procClobber;
|
||||
}
|
||||
|
||||
private List<String> getNonClobberedRegisterNames(CpuClobber procClobber) {
|
||||
List<String> notClobberedRegisters = new ArrayList<>();
|
||||
if(!procClobber.isRegisterA()) {
|
||||
notClobberedRegisters.add("a");
|
||||
/**
|
||||
* Get the clobbered registers
|
||||
*
|
||||
* @param procClobber CPU clobber from running the interrupt routine
|
||||
* @return The clobbered registers as a string. "axyz" is all registers, "" is none.
|
||||
*/
|
||||
private String getClobberedRegisterNames(CpuClobber procClobber) {
|
||||
String clobberedRegisters = "";
|
||||
if(procClobber.isRegisterA()) {
|
||||
clobberedRegisters += "a";
|
||||
}
|
||||
if(!procClobber.isRegisterX()) {
|
||||
notClobberedRegisters.add("x");
|
||||
if(procClobber.isRegisterX()) {
|
||||
clobberedRegisters += "x";
|
||||
}
|
||||
if(!procClobber.isRegisterY()) {
|
||||
notClobberedRegisters.add("y");
|
||||
if(procClobber.isRegisterY()) {
|
||||
clobberedRegisters += "y";
|
||||
}
|
||||
return notClobberedRegisters;
|
||||
if(procClobber.isRegisterZ()) {
|
||||
clobberedRegisters += "z";
|
||||
}
|
||||
return clobberedRegisters;
|
||||
}
|
||||
|
||||
private void pruneNonClobberedInterruptLines(AsmChunk interruptEntryExit, List<String> notClobberedRegisters) {
|
||||
ListIterator<AsmLine> entryLines = interruptEntryExit.getLines().listIterator();
|
||||
while(entryLines.hasNext()) {
|
||||
AsmLine line = entryLines.next();
|
||||
for(String notClobberedReg : notClobberedRegisters) {
|
||||
final String lineAsm = line.getAsm();
|
||||
if(lineAsm.contains("ld"+notClobberedReg) || lineAsm.contains("st"+notClobberedReg) || lineAsm.contains("reg"+notClobberedReg)) {
|
||||
// Found an A/X/Y in the asm where A/X/Y is not clobbered - remove the line
|
||||
getLog().append("Removing interrupt register storage "+line.toString()+" in "+interruptEntryExit.getIndex()+" "+interruptEntryExit.getSource());
|
||||
entryLines.remove();
|
||||
}
|
||||
/**
|
||||
* Replace the current code with the proper version handling only the clobbered registers
|
||||
*
|
||||
* @param interruptAsmChunk The AsmFragment representing an interrupt entry/exit
|
||||
* @param clobberedRegisters The clobbered registers
|
||||
*/
|
||||
private void updateClobberFragment(AsmChunk interruptAsmChunk, String clobberedRegisters) {
|
||||
// find the clobber fragment sub-name
|
||||
String clobberName = "clob" + clobberedRegisters;
|
||||
if(clobberedRegisters.equals(""))
|
||||
clobberName = "none";
|
||||
String allRegisters = "axy" + (getProgram().getTargetCpu().getCpu65xx().hasRegisterZ() ? "z" : "");
|
||||
if(clobberedRegisters.equals(allRegisters))
|
||||
clobberName = "all";
|
||||
|
||||
// Find the interrupt type name (including "isr_" and "_entry"/"_exit"
|
||||
String interruptType = interruptAsmChunk.getSource();
|
||||
interruptType = interruptType.substring(("interrupt(".length()), interruptType.length() - 1);
|
||||
|
||||
// Find the correct clobber name based on the clobbered registers
|
||||
final String interruptSignatureFinal = interruptType.replace("clobber", clobberName);
|
||||
AsmFragmentInstanceSpecBuilder interruptFragment = AsmFragmentInstanceSpecBuilder.interrupt(interruptSignatureFinal, getProgram());
|
||||
String interruptFragmentName = interruptFragment.getAsmFragmentInstanceSpec().getSignature();
|
||||
|
||||
// Generate the fragment
|
||||
final AsmFragmentTemplateSynthesizer cpuSynthesizer = getProgram().getAsmFragmentMasterSynthesizer().getSynthesizer(getProgram().getTargetCpu());
|
||||
final AsmFragmentInstance fragmentInstance = cpuSynthesizer.getFragmentInstance(interruptFragment.getAsmFragmentInstanceSpec(), getProgram().getLog());
|
||||
interruptAsmChunk.setFragment(fragmentInstance.getFragmentName());
|
||||
final AsmProgram asmLines = new AsmProgram(getProgram().getTargetCpu());
|
||||
asmLines.startChunk(getProgram().getScope().getRef(), interruptAsmChunk.getStatementIdx(), interruptAsmChunk.getSource());
|
||||
fragmentInstance.generate(asmLines);
|
||||
|
||||
// Replace the chunk lines with the generated lines
|
||||
final List<AsmLine> interruptAsmChunkLines = interruptAsmChunk.getLines();
|
||||
int line_idx = interruptAsmChunkLines.get(0).getIndex();
|
||||
boolean hasScopeEnd = interruptAsmChunkLines.get(interruptAsmChunkLines.size() - 1) instanceof AsmScopeEnd;
|
||||
interruptAsmChunkLines.clear();
|
||||
interruptAsmChunk.setSource("interrupt(" + interruptFragmentName+ ")");
|
||||
for(AsmChunk chunk : asmLines.getChunks()) {
|
||||
for(AsmLine line : chunk.getLines()) {
|
||||
interruptAsmChunk.addLine(line);
|
||||
line.setIndex(line_idx++);
|
||||
if(line instanceof AsmLabel) ((AsmLabel) line).setDontOptimize(true);
|
||||
}
|
||||
}
|
||||
if(hasScopeEnd)
|
||||
interruptAsmChunkLines.add(new AsmScopeEnd());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
"link": "asm6502.ld",
|
||||
"start_address": "0x2000",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "hardware_all",
|
||||
"emulator": "x64sc"
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
"extension": "a26",
|
||||
"link": "atari2600.ld",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "hardware_all",
|
||||
"zp_reserve": [ "0x00..0x7f" ],
|
||||
"encoding": "screencode_atari",
|
||||
"defines": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"description": "Atari XL/XE executable XEX file with a single segment.",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "hardware_all",
|
||||
"link": "atarixl.ld",
|
||||
"start_address": "0x2000",
|
||||
"zp_reserve": [ "0x00..0x7f" ],
|
||||
|
@ -4,6 +4,7 @@
|
||||
"link": "c64.ld",
|
||||
"start_address": "0x080d",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "rom_min_c64",
|
||||
"emulator": "x64sc",
|
||||
"defines": {
|
||||
"__C64__": 1
|
||||
|
@ -3,6 +3,7 @@
|
||||
"link": "c64basic.ld",
|
||||
"start_address": "0x080d",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "rom_min_c64",
|
||||
"emulator": "x64sc",
|
||||
"defines": {
|
||||
"__C64__": 1
|
||||
|
@ -4,6 +4,7 @@
|
||||
"link": "cx16.ld",
|
||||
"start_address": "0x080d",
|
||||
"cpu": "WDC65C02",
|
||||
"interrupt": "rom_min_cx16",
|
||||
"emulator": "x16emu -debug -run -scale 2 -prg",
|
||||
"defines": {
|
||||
"__CX16__": 1
|
||||
|
@ -4,6 +4,7 @@
|
||||
"link": "mega65.ld",
|
||||
"start_address": "0x2017",
|
||||
"cpu": "MEGA45GS02",
|
||||
"interrupt": "rom_min_mega65",
|
||||
"emulator": "xmega65 -prg",
|
||||
"defines": {
|
||||
"__MEGA65__": 1
|
||||
|
@ -4,6 +4,7 @@
|
||||
"link": "mega65_c64.ld",
|
||||
"start_address": "0x080d",
|
||||
"cpu": "MEGA45GS02",
|
||||
"interrupt": "rom_min_c64",
|
||||
"emulator": "xmega65 -prg",
|
||||
"defines": {
|
||||
"__MEGA65__": 1,
|
||||
|
@ -2,10 +2,11 @@
|
||||
"description": "Nintendo Entertainment System (NES) ROM (Mapper 0 NROM, Vertical Mirroring).",
|
||||
"extension": "nes",
|
||||
"link": "nes.ld",
|
||||
"cpu": "MOS6502X",
|
||||
"emulator": "Nestopia",
|
||||
"cpu": "ROM6502X",
|
||||
"interrupt": "hardware_all",
|
||||
"zp_reserve": [ ],
|
||||
"defines": {
|
||||
"__NES__": 1
|
||||
}
|
||||
},
|
||||
"emulator": "Nestopia"
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
"link": "plus4.ld",
|
||||
"start_address": "0x100d",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "rom_min_plus4",
|
||||
"emulator": "xplus4",
|
||||
"defines": {
|
||||
"__PLUS4__": 1
|
||||
|
@ -3,6 +3,7 @@
|
||||
"link": "plus4basic.ld",
|
||||
"start_address": "0x100d",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "rom_min_plus4",
|
||||
"emulator": "xplus4",
|
||||
"defines": {
|
||||
"__PLUS4__": 1
|
||||
|
@ -4,6 +4,7 @@
|
||||
"link": "vic20.ld",
|
||||
"start_address": "0x100d",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "rom_min_vic20",
|
||||
"emulator": "xvic",
|
||||
"defines": {
|
||||
"__VIC20__": 1
|
||||
|
@ -3,6 +3,7 @@
|
||||
"link": "vic20basic.ld",
|
||||
"start_address": "0x100d",
|
||||
"cpu": "MOS6502X",
|
||||
"interrupt": "rom_min_vic20",
|
||||
"emulator": "xvic",
|
||||
"defines": {
|
||||
"__VIC20__": 1
|
||||
|
@ -3852,6 +3852,16 @@ public class TestPrograms {
|
||||
compileAndCompare("irq-kernel-minimal.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIrqUnknownType() throws IOException, URISyntaxException {
|
||||
assertError("irq-unknown-type.c", "Interrupt type not supported unknown", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIrqPragma() throws IOException, URISyntaxException {
|
||||
compileAndCompare("irq-pragma.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIrqHyperscreen() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/irq/irq-hyperscreen.c");
|
||||
|
@ -50,7 +50,7 @@ void init_irq() {
|
||||
}
|
||||
|
||||
// Interrupt Routine counting frames
|
||||
interrupt(hardware_clobber) void irq() {
|
||||
__interrupt(hardware_clobber) void irq() {
|
||||
*BG_COLOR = WHITE;
|
||||
if(frame_cnt) frame_cnt++;
|
||||
*BG_COLOR = BLACK;
|
||||
|
@ -57,7 +57,7 @@ void init_irq() {
|
||||
}
|
||||
|
||||
// Interrupt Routine counting frames
|
||||
interrupt(hardware_clobber) void irq() {
|
||||
__interrupt(hardware_clobber) void irq() {
|
||||
*BG_COLOR = WHITE;
|
||||
if(frame_cnt) frame_cnt++;
|
||||
*BG_COLOR = BLACK;
|
||||
|
@ -66,7 +66,7 @@ void init_irq() {
|
||||
}
|
||||
|
||||
// Interrupt Routine counting frames
|
||||
interrupt(hardware_clobber) void irq() {
|
||||
__interrupt(hardware_clobber) void irq() {
|
||||
*BG_COLOR = WHITE;
|
||||
if(frame_cnt) frame_cnt++;
|
||||
*BG_COLOR = BLACK;
|
||||
|
@ -12,7 +12,7 @@ void main() {
|
||||
|
||||
volatile byte irq_raster_next = 0;
|
||||
|
||||
interrupt(hardware_clobber) void irq() {
|
||||
__interrupt(hardware_clobber) void irq() {
|
||||
*BORDER_COLOR = DARK_GREY;
|
||||
irq_raster_next += 21;
|
||||
// Setup next interrupt
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#pragma link("ataritempest.ld")
|
||||
#pragma extension("bin")
|
||||
#pragma cpu(ROM6502X)
|
||||
|
||||
char* const BG_COLOR = 0xc01a;
|
||||
|
||||
@ -17,7 +18,7 @@ void entryPoint() {
|
||||
SCREEN[i] = MESSAGE[i];
|
||||
}
|
||||
|
||||
void interrupt(HARDWARE_ALL) nmiHandler() {
|
||||
void __interrupt(hardware_clobber) nmiHandler() {
|
||||
(*BG_COLOR)++;
|
||||
}
|
||||
|
||||
|
@ -305,7 +305,7 @@ void setupRasterIrq(unsigned int raster, void()* irqRoutine) {
|
||||
const char RASTER_IRQ_TOP = 0x30;
|
||||
|
||||
// Raster Interrupt at the top of the screen
|
||||
interrupt(hardware_all) void irqTop() {
|
||||
__interrupt(hardware_clobber) void irqTop() {
|
||||
if(DEBUG) {
|
||||
for( char i: 0..4) {}
|
||||
*BORDER_COLOR = WHITE;
|
||||
@ -325,7 +325,7 @@ interrupt(hardware_all) void irqTop() {
|
||||
const char RASTER_IRQ_MIDDLE = 0xff;
|
||||
|
||||
// Raster Interrupt at the bottom of the screen
|
||||
interrupt(hardware_all) void irqBottom() {
|
||||
__interrupt(hardware_clobber) void irqBottom() {
|
||||
if(DEBUG) {
|
||||
for( char i: 0..4) {}
|
||||
*BORDER_COLOR = WHITE;
|
||||
|
@ -91,7 +91,7 @@ volatile char scroll_y;
|
||||
char * volatile vram_update_list;
|
||||
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
interrupt(hardware_stack) void vblank() {
|
||||
__interrupt(hardware_clobber) void vblank() {
|
||||
// Transfer any queued data to the PPU
|
||||
lnListTransfer();
|
||||
// DMA transfer the entire sprite buffer to the PPU
|
||||
|
@ -13,7 +13,7 @@ typedef unsigned short uword;
|
||||
// RESET Called when the NES is reset, including when it is turned on.
|
||||
void main();
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
interrupt(hardware_stack) void vblank();
|
||||
__interrupt(hardware_clobber) void vblank();
|
||||
|
||||
// Wait for next vblank
|
||||
// flags: 0, lfBlank or lfSplit (see below)
|
||||
|
@ -129,7 +129,7 @@ int main(void)
|
||||
}
|
||||
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
interrupt(hardware_stack) void vblank() {
|
||||
__interrupt(hardware_clobber) void vblank() {
|
||||
// Set scroll
|
||||
PPU->PPUSCROLL = 0;
|
||||
PPU->PPUSCROLL = scroll_y;
|
||||
|
@ -129,7 +129,7 @@ int main(void)
|
||||
}
|
||||
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
interrupt(hardware_stack) void vblank() {
|
||||
__interrupt(hardware_clobber) void vblank() {
|
||||
// Set scroll
|
||||
PPU->PPUSCROLL = 0;
|
||||
PPU->PPUSCROLL = scroll_y;
|
||||
|
@ -125,7 +125,7 @@ void setup_irq() {
|
||||
}
|
||||
|
||||
// Interrupt Routine 1: Just above last text line.
|
||||
interrupt(kernel_min) void irq_bottom_1() {
|
||||
__interrupt void irq_bottom_1() {
|
||||
// Change border color
|
||||
VICII->BORDER_COLOR = DARK_GREY;
|
||||
// Show the cycle counter
|
||||
@ -138,7 +138,7 @@ interrupt(kernel_min) void irq_bottom_1() {
|
||||
}
|
||||
|
||||
// Interrupt Routine 2
|
||||
interrupt(kernel_keyboard) void irq_bottom_2() {
|
||||
__interrupt(rom_sys_c64) void irq_bottom_2() {
|
||||
// Change border color
|
||||
VICII->BORDER_COLOR = BLACK;
|
||||
// Show the current canvas (unless a key is being pressed)
|
||||
|
@ -136,7 +136,7 @@ void plex_move() {
|
||||
volatile bool frame_done = false;
|
||||
|
||||
// Show sprites from the multiplexer, rescheduling the IRQ as many times as needed
|
||||
interrupt(kernel_min) void plex_irq() {
|
||||
__interrupt void plex_irq() {
|
||||
asm { sei }
|
||||
//*BORDER_COLOR = WHITE;
|
||||
// Show sprites until finding one that should not be shown until a few raster lines later
|
||||
|
@ -56,7 +56,7 @@ void sprites_irq_init() {
|
||||
// Raster Interrupt Routine - sets up the sprites covering the playfield
|
||||
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
|
||||
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
|
||||
interrupt(hardware_clobber) void sprites_irq() {
|
||||
__interrupt(hardware_clobber) void sprites_irq() {
|
||||
//(*BG_COLOR)++;
|
||||
// Clear decimal flag (because it is used by the score algorithm)
|
||||
asm { cld }
|
||||
|
@ -17,7 +17,7 @@ void main() {
|
||||
}
|
||||
|
||||
// Interrupt Routine
|
||||
interrupt(kernel_keyboard) void irq() {
|
||||
__interrupt(rom_sys_c64) void irq() {
|
||||
PLEX_SCREEN_PTR1[idx]++;
|
||||
PLEX_SCREEN_PTR2[idx]++;
|
||||
idx++;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Example program for the Commander X16
|
||||
// Displays raster bars in the border
|
||||
|
||||
#pragma target(cx16)
|
||||
#pragma target(cx16)
|
||||
#include <cx16.h>
|
||||
#include <6502.h>
|
||||
#include <string.h>
|
||||
@ -42,7 +42,7 @@ volatile char cnt = 2;
|
||||
volatile char sin_idx = 100;
|
||||
|
||||
// LINE Interrupt Routine
|
||||
void irq_line() {
|
||||
__interrupt void irq_line() {
|
||||
// Update the border
|
||||
*VERA_CTRL |= VERA_DCSEL;
|
||||
*VERA_DC_HSTART = hstart;
|
||||
@ -84,15 +84,4 @@ void irq_line() {
|
||||
|
||||
// Reset the LINE interrupt
|
||||
*VERA_ISR = VERA_LINE;
|
||||
// Exit CX16 KERNAL IRQ
|
||||
asm {
|
||||
// soft exit (keep kernal running)
|
||||
// jmp $e034
|
||||
// hard exit (no kernal activity)
|
||||
ply
|
||||
plx
|
||||
pla
|
||||
rti
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
#define NUM_SPRITES 32
|
||||
|
||||
// A 64*64 8bpp TUT sprite
|
||||
// A 64*64 8bpp TUT sprite and palette
|
||||
align(0x1000) char SPRITE_PIXELS[64*64+0x200] = kickasm(resource "tut.png") {{
|
||||
.var pic = LoadPicture("tut.png")
|
||||
// palette: rgb->idx
|
||||
@ -16,8 +16,10 @@ align(0x1000) char SPRITE_PIXELS[64*64+0x200] = kickasm(resource "tut.png") {{
|
||||
.var palList = List()
|
||||
// Next palette index
|
||||
.var nxt_idx = 0;
|
||||
// Extract palette while outputting pixels as palete index values
|
||||
.for (var y=0; y<64; y++) {
|
||||
.for (var x=0;x<64; x++) {
|
||||
// Find palette index (add if not known)
|
||||
.var rgb = pic.getPixel(x,y);
|
||||
.var idx = palette.get(rgb)
|
||||
.if(idx==null) {
|
||||
@ -25,11 +27,12 @@ align(0x1000) char SPRITE_PIXELS[64*64+0x200] = kickasm(resource "tut.png") {{
|
||||
.eval palette.put(rgb,idx);
|
||||
.eval palList.add(rgb)
|
||||
}
|
||||
// Output pixel index
|
||||
// Output pixel as palette index
|
||||
.byte idx
|
||||
}
|
||||
}
|
||||
// Output sprite palette (offset 64*64 bytes)
|
||||
.if(nxt_idx>256) .error "Image has too many colours "+nxt_idx
|
||||
// Output sprite palette (at offset 64*64 bytes)
|
||||
.for(var i=0;i<256;i++) {
|
||||
.var rgb = palList.get(i)
|
||||
.var red = floor(rgb / [256*256])
|
||||
@ -40,7 +43,6 @@ align(0x1000) char SPRITE_PIXELS[64*64+0x200] = kickasm(resource "tut.png") {{
|
||||
// bits bits 0-3 red
|
||||
.byte red/16
|
||||
}
|
||||
|
||||
}};
|
||||
|
||||
// Address to use for sprite pixels in VRAM
|
||||
@ -90,7 +92,7 @@ volatile unsigned int sin_idx_x = 119;
|
||||
volatile unsigned int sin_idx_y = 79;
|
||||
|
||||
// VSYNC Interrupt Routine
|
||||
void irq_vsync() {
|
||||
__interrupt(rom_sys_cx16) void irq_vsync() {
|
||||
// Move the sprite around
|
||||
if(++sin_idx_x==SINX_LEN) sin_idx_x = 0;
|
||||
if(--sin_idx_y==0xffff) sin_idx_y = SINY_LEN-1;
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <cx16.h>
|
||||
|
||||
void main() {
|
||||
|
||||
// Copy message to screen one char at a time
|
||||
char MSG[] = "hello world!";
|
||||
char* vaddr = DEFAULT_SCREEN;
|
||||
@ -13,7 +12,6 @@ void main() {
|
||||
vpoke(0, vaddr++, MSG[i]); // Message
|
||||
vpoke(0, vaddr++, 0x21); // Red background, White foreground
|
||||
}
|
||||
|
||||
// Copy message (and colors) to screen using memcpy_to_vram
|
||||
char MSG2[] = "h e l l o w o r l d ! "; // Space is 0x20, red background black foreground
|
||||
memcpy_to_vram(0, DEFAULT_SCREEN+0x100, MSG2, sizeof(MSG2));
|
||||
|
@ -24,7 +24,7 @@ void main() {
|
||||
}
|
||||
|
||||
// Interrupt Routine 1
|
||||
interrupt(hardware_stack) void irq_bottom_1() {
|
||||
__interrupt(hardware_clobber) void irq_bottom_1() {
|
||||
VICII->BORDER_COLOR = WHITE;
|
||||
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
|
||||
VICII->CONTROL1 &= ($ff^VIC_RSEL);
|
||||
@ -37,7 +37,7 @@ interrupt(hardware_stack) void irq_bottom_1() {
|
||||
}
|
||||
|
||||
// Interrupt Routine 2
|
||||
interrupt(hardware_stack) void irq_bottom_2() {
|
||||
__interrupt(hardware_clobber) void irq_bottom_2() {
|
||||
VICII->BORDER_COLOR = WHITE;
|
||||
// Set screen height back to 25 lines (preparing for the next screen)
|
||||
VICII->CONTROL1 |= VIC_RSEL;
|
||||
|
@ -61,7 +61,7 @@ void main() {
|
||||
}
|
||||
|
||||
// Raster IRQ routine
|
||||
interrupt(hardware_stack) void irq() {
|
||||
__interrupt(hardware_clobber) void irq() {
|
||||
// Acknowledge the IRQ
|
||||
VICII->IRQ_STATUS = IRQ_RASTER;
|
||||
// Color border
|
||||
|
@ -102,7 +102,7 @@ volatile char greet_zoomx;
|
||||
volatile char greet_idx;
|
||||
|
||||
// BIG INTERRUPT LOOP
|
||||
interrupt(hardware_stack) void irq() {
|
||||
__interrupt(hardware_clobber) void irq() {
|
||||
// force NTSC every frame (hehe)
|
||||
VICIV->RASLINE0 |= 0x80;
|
||||
// Acknowledge the IRQ
|
||||
|
@ -28,7 +28,7 @@ void main() {
|
||||
}
|
||||
|
||||
// Raster IRQ Routine playing music
|
||||
interrupt(kernel_keyboard) void irq_play() {
|
||||
__interrupt(rom_sys_c64) void irq_play() {
|
||||
(VICII->BORDER_COLOR)++;
|
||||
// Play SID
|
||||
(*musicPlay)();
|
||||
|
@ -46,7 +46,7 @@ volatile char x_scroll;
|
||||
volatile char y_scroll;
|
||||
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
interrupt(hardware_stack) void vblank() {
|
||||
__interrupt void vblank() {
|
||||
// Read controller 1
|
||||
char joy = readJoy1();
|
||||
if(joy&JOY_DOWN) {
|
||||
|
@ -30,7 +30,7 @@ void main() {
|
||||
}
|
||||
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
interrupt(hardware_stack) void vblank() {
|
||||
__interrupt void vblank() {
|
||||
|
||||
// Read controller 1
|
||||
char joy = readJoy1();
|
||||
|
@ -31,7 +31,7 @@ volatile char x_sin_idx = 73;
|
||||
volatile char x_sin_idx_2 = 82;
|
||||
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
interrupt(hardware_stack) void vblank() {
|
||||
__interrupt void vblank() {
|
||||
// Set scroll
|
||||
PPU->PPUSCROLL = 0;
|
||||
PPU->PPUSCROLL = 0;
|
||||
|
@ -32,7 +32,7 @@ void main() {
|
||||
asm { cli }
|
||||
}
|
||||
|
||||
interrupt(hardware_all) void nmi() {
|
||||
__interrupt(hardware_clobber) void nmi() {
|
||||
(VICII->BORDER_COLOR)++;
|
||||
asm { lda CIA2_INTERRUPT }
|
||||
SID->VOLUME_FILTER_MODE = *sample & $0f;
|
||||
@ -40,7 +40,7 @@ interrupt(hardware_all) void nmi() {
|
||||
(VICII->BORDER_COLOR)--;
|
||||
}
|
||||
|
||||
interrupt(hardware_all) void nmi2() {
|
||||
__interrupt(hardware_clobber) void nmi2() {
|
||||
(VICII->BORDER_COLOR)++;
|
||||
asm { lda CIA2_INTERRUPT }
|
||||
SID->VOLUME_FILTER_MODE = *sample >> 4;
|
||||
|
@ -8,7 +8,7 @@ void main() {
|
||||
*KERNEL_IRQ = &irq;
|
||||
}
|
||||
|
||||
interrupt void irq() {
|
||||
__interrupt void irq() {
|
||||
SCREEN[40] = col1++;
|
||||
SCREEN[41] = col2++;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ void main() {
|
||||
}
|
||||
}
|
||||
|
||||
interrupt void irq() {
|
||||
__interrupt void irq() {
|
||||
// Acknowledge the IRQ
|
||||
*IRQ_STATUS = 1;
|
||||
asm { lda $dc0d }
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user