1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-18 08:30:18 +00:00

Added tests showcasing problems with volatiles.

This commit is contained in:
jespergravgaard 2018-12-24 11:12:47 +01:00
parent 8ef005e64d
commit b92ea8415b
16 changed files with 3188 additions and 1176 deletions

View File

@ -44,6 +44,17 @@ public class TestPrograms {
AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false);
}
@Test
public void testInterruptVolatileReuseProblem() throws IOException, URISyntaxException {
compileAndCompare("interrupt-volatile-reuse-problem");
}
@Test
public void testInitVolatiles() throws IOException, URISyntaxException {
compileAndCompare("init-volatiles");
}
@Test
public void testInterruptVolatileWrite() throws IOException, URISyntaxException {
compileAndCompare("test-interrupt-volatile-write");

View File

@ -1,12 +1,21 @@
import "c64"
byte* PLAYFIELD_SPRITES = $2000;
byte* PLAYFIELD_CHARSET = $1000;
byte* PLAYFIELD_SCREEN = $0400;
// Address of the sprites covering the playfield
const byte* PLAYFIELD_SPRITES = $2000;
// Address for the charset
const byte* PLAYFIELD_CHARSET = $1000;
// Address of the screen
const byte* PLAYFIELD_SCREEN = $0400;
// Screen Sprite pointers
const byte* PLAYFIELD_SPRITE_PTRS = (PLAYFIELD_SCREEN+SPRITE_PTRS);
void main() {
init_sprites();
init_irq();
while(true) {
(*PLAYFIELD_SCREEN)++;
}
}
// Setup the sprites
@ -15,33 +24,34 @@ void init_sprites() {
*D018 = toD018(PLAYFIELD_SCREEN, PLAYFIELD_CHARSET);
*SPRITES_ENABLE = %00001111;
*SPRITES_EXPAND_X = *SPRITES_EXPAND_Y = *SPRITES_MC = 0;
byte* sprites_ptr = PLAYFIELD_SCREEN+SPRITE_PTRS;
byte xpos = 24+14*8;
byte ypos = 50;
byte ptr = toSpritePtr(PLAYFIELD_SPRITES);
for(byte s:0..3) {
byte s2 = s<<1;
SPRITES_XPOS[s2] = xpos;
SPRITES_YPOS[s2] = ypos;
SPRITES_COLS[s] = BLACK;
sprites_ptr[s] = ptr;
xpos = xpos+24;
ptr++;
}
}
// The line of the first IRQ - $30 is 2 lines before the start of the screen
const byte IRQ_RASTER_FIRST = $30;
// The line of the first IRQ - 48 is 2 lines before the start of the screen
const byte IRQ_RASTER_FIRST = 48;
// The raster line of the next IRQ
volatile byte irq_raster_next = IRQ_RASTER_FIRST;
// Counting the 10 IRQs
volatile byte irq_cnt = 0;
// Y-pos of the sprites on the next IRQ
volatile byte irq_sprite_ypos = 50;
// Y-pos of the sprites on the next IRQ
volatile byte irq_sprite_ptr = toSpritePtr(PLAYFIELD_SPRITES);
// Counting the 10 IRQs
volatile byte irq_cnt = 0;
// Setup the IRQ
void init_irq() {
// Stup the first IRQ position
irq_raster_next = IRQ_RASTER_FIRST;
irq_sprite_ypos = 50;
irq_sprite_ptr = toSpritePtr(PLAYFIELD_SPRITES);
irq_cnt = 0;
asm { sei }
// Disable CIA 1 Timer IRQ
*CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR;
@ -60,7 +70,7 @@ void init_irq() {
// Repeats 10 timers every 21 lines from line IRQ_RASTER_FIRST
interrupt(kernel_min) void irq() {
*BORDERCOL = *BGCOL = WHITE;
*BORDERCOL = DARK_GREY;
// Place the sprites
SPRITES_YPOS[0] = irq_sprite_ypos;
@ -68,14 +78,27 @@ interrupt(kernel_min) void irq() {
SPRITES_YPOS[4] = irq_sprite_ypos;
SPRITES_YPOS[6] = irq_sprite_ypos;
// Wait for the y-position before changing sprite pointers
do {
} while(*RASTER!=irq_sprite_ypos);
byte ptr = irq_sprite_ptr;
PLAYFIELD_SPRITE_PTRS[0] = ptr++;
PLAYFIELD_SPRITE_PTRS[1] = ptr;
PLAYFIELD_SPRITE_PTRS[2] = ptr++;
PLAYFIELD_SPRITE_PTRS[3] = ptr;
// Find next raster line / sprite positions
if(++irq_cnt==10) {
irq_cnt = 0;
irq_raster_next = IRQ_RASTER_FIRST;
irq_sprite_ypos = 50;
irq_sprite_ptr = toSpritePtr(PLAYFIELD_SPRITES);
} else {
irq_raster_next += 21;
irq_sprite_ypos += 21;
irq_sprite_ypos += 21;
irq_sprite_ptr += 3;
}
// Acknowledge the IRQ and setup the next one
@ -83,7 +106,6 @@ interrupt(kernel_min) void irq() {
*IRQ_STATUS = IRQ_RASTER;
*BORDERCOL = BLACK;
*BGCOL = BLUE;
}

View File

@ -0,0 +1,10 @@
// Illustrates a problem where volatiles with initializers are initialized outside the main()-routine
volatile byte x = 12;
void main() {
while(++x<50) {
}
x = 0;
}

View File

@ -0,0 +1,28 @@
// Illustrates problem where volatiles reuse ZP addresses of other variables - and reuses the same address for multiple volatiles
const void()** KERNEL_IRQ = $0314;
const byte* BORDERCOL = $d021;
const byte* BGCOL = $d020;
volatile byte col1 = 0;
volatile byte col2 = 8;
void main() {
byte* SCREEN=$400;
byte qwe = 32;
byte asd = 0;
byte row = 12;
for(byte x:0..10) {
SCREEN[x] = ++row;
++qwe;
asd += qwe;
}
SCREEN[0] = qwe;
SCREEN[1] = asd;
*KERNEL_IRQ = &irq;
}
interrupt(kernel_min) void irq() {
asm {
lda $dc0d
}
*BGCOL = col1++;
*BORDERCOL = col2++;
}

View File

@ -10,7 +10,6 @@
.label SPRITES_MC = $d01c
.label SPRITES_EXPAND_X = $d01d
.label BORDERCOL = $d020
.label BGCOL = $d021
.label SPRITES_COLS = $d027
.label VIC_CONTROL = $d011
.label D018 = $d018
@ -23,28 +22,43 @@
.label CIA2_PORT_A_DDR = $dd02
.label KERNEL_IRQ = $314
.const BLACK = 0
.const WHITE = 1
.const BLUE = 6
.const DARK_GREY = $b
.label PLAYFIELD_SPRITES = $2000
.label PLAYFIELD_CHARSET = $1000
.label PLAYFIELD_SCREEN = $400
.const IRQ_RASTER_FIRST = $30
.label PLAYFIELD_SPRITE_PTRS = PLAYFIELD_SCREEN+SPRITE_PTRS
.const toSpritePtr1_return = PLAYFIELD_SPRITES>>6
.label irq_raster_next = 2
.label irq_cnt = 2
.label irq_sprite_ypos = 2
.label irq_sprite_ptr = 2
.label irq_cnt = 2
lda #IRQ_RASTER_FIRST
sta irq_raster_next
lda #0
sta irq_cnt
lda #$32
sta irq_sprite_ypos
lda #toSpritePtr1_return
sta irq_sprite_ptr
lda #0
sta irq_cnt
jsr main
main: {
jsr init_sprites
jsr init_irq
rts
b2:
inc PLAYFIELD_SCREEN
jmp b2
}
init_irq: {
.const toSpritePtr2_return = PLAYFIELD_SPRITES>>6
lda #IRQ_RASTER_FIRST
sta irq_raster_next
lda #$32
sta irq_sprite_ypos
lda #toSpritePtr2_return
sta irq_sprite_ptr
lda #0
sta irq_cnt
sei
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
@ -63,13 +77,9 @@ init_irq: {
rts
}
init_sprites: {
.const ypos = $32
.label sprites_ptr = PLAYFIELD_SCREEN+SPRITE_PTRS
.const toSpritePtr1_return = PLAYFIELD_SPRITES>>6
.const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_SCREEN)>>6
.const toD0181_return = (>(PLAYFIELD_SCREEN&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f
.label xpos = 2
.label ptr = 3
lda #3
sta CIA2_PORT_A_DDR
lda #vicSelectGfxBank1_toDd001_return
@ -82,36 +92,29 @@ init_sprites: {
sta SPRITES_MC
sta SPRITES_EXPAND_Y
sta SPRITES_EXPAND_X
lda #toSpritePtr1_return
sta ptr
lda #$18+$e*8
sta xpos
ldy #0
ldx #0
b1:
tya
txa
asl
tax
tay
lda xpos
sta SPRITES_XPOS,x
lda #ypos
sta SPRITES_YPOS,x
sta SPRITES_XPOS,y
lda #BLACK
sta SPRITES_COLS,y
lda ptr
sta sprites_ptr,y
sta SPRITES_COLS,x
lda #$18
clc
adc xpos
sta xpos
inc ptr
iny
cpy #4
inx
cpx #4
bne b1
rts
}
irq: {
lda #WHITE
sta BGCOL
.const toSpritePtr2_return = PLAYFIELD_SPRITES>>6
lda #DARK_GREY
sta BORDERCOL
lda irq_sprite_ypos
sta SPRITES_YPOS
@ -121,10 +124,21 @@ irq: {
sta SPRITES_YPOS+4
lda irq_sprite_ypos
sta SPRITES_YPOS+6
b1:
lda RASTER
cmp irq_sprite_ypos
bne b1
ldx irq_sprite_ptr
stx PLAYFIELD_SPRITE_PTRS
inx
stx PLAYFIELD_SPRITE_PTRS+1
stx PLAYFIELD_SPRITE_PTRS+2
inx
stx PLAYFIELD_SPRITE_PTRS+3
inc irq_cnt
lda irq_cnt
cmp #$a
beq b1
beq b2
lda #$15
clc
adc irq_raster_next
@ -133,24 +147,28 @@ irq: {
clc
adc irq_sprite_ypos
sta irq_sprite_ypos
b2:
lda #3
clc
adc irq_sprite_ptr
sta irq_sprite_ptr
b3:
lda irq_raster_next
sta RASTER
lda #IRQ_RASTER
sta IRQ_STATUS
lda #BLACK
sta BORDERCOL
lda #BLUE
sta BGCOL
jmp $ea81
b1:
b2:
lda #0
sta irq_cnt
lda #IRQ_RASTER_FIRST
sta irq_raster_next
lda #$32
sta irq_sprite_ypos
jmp b2
lda #toSpritePtr2_return
sta irq_sprite_ptr
jmp b3
}
.pc = PLAYFIELD_SPRITES "Inline"
.var sprites = LoadPicture("nes-playfield.png", List().add($010101, $000000))

View File

@ -2,11 +2,17 @@
[0] phi()
to:@6
@6: scope:[] from @begin
[1] (byte) irq_raster_next#0 ← (const byte) IRQ_RASTER_FIRST#0
[2] (byte) irq_cnt#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[3] (byte) irq_sprite_ypos#0 ← (byte/signed byte/word/signed word/dword/signed dword) 50
[1] (byte) irq_raster_next#2 ← (const byte) IRQ_RASTER_FIRST#0
[2] (byte) irq_sprite_ypos#2 ← (byte/signed byte/word/signed word/dword/signed dword) 50
to:toSpritePtr1
toSpritePtr1: scope:[] from @6
[3] phi()
to:@9
@9: scope:[] from toSpritePtr1
[4] (byte) irq_sprite_ptr#2 ← (const byte) toSpritePtr1_return#0
[5] (byte) irq_cnt#19 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:@8
@8: scope:[] from @6
@8: scope:[] from @9
kickasm(location (const byte*) PLAYFIELD_SPRITES#0) {{ .var sprites = LoadPicture("nes-playfield.png", List().add($010101, $000000))
.for(var sy=0;sy<10;sy++) {
.for(var sx=0;sx<3;sx++) {
@ -19,101 +25,120 @@
}
}
}}
[5] call main
[7] call main
to:@end
@end: scope:[] from @8
[6] phi()
[8] phi()
main: scope:[main] from @8
[7] phi()
[8] call init_sprites
to:main::@1
main::@1: scope:[main] from main
[9] phi()
[10] call init_irq
to:main::@return
main::@return: scope:[main] from main::@1
[11] return
to:@return
init_irq: scope:[init_irq] from main::@1
[10] call init_sprites
to:main::@7
main::@7: scope:[main] from main
[11] phi()
[12] call init_irq
to:main::@2
main::@2: scope:[main] from main::@2 main::@7
[13] *((const byte*) PLAYFIELD_SCREEN#0) ← ++ *((const byte*) PLAYFIELD_SCREEN#0)
to:main::@2
init_irq: scope:[init_irq] from main::@7
[14] (byte) irq_raster_next#11 ← (const byte) IRQ_RASTER_FIRST#0
[15] (byte) irq_sprite_ypos#11 ← (byte/signed byte/word/signed word/dword/signed dword) 50
to:init_irq::toSpritePtr2
init_irq::toSpritePtr2: scope:[init_irq] from init_irq
[16] phi()
to:init_irq::@1
init_irq::@1: scope:[init_irq] from init_irq::toSpritePtr2
[17] (byte) irq_sprite_ptr#3 ← (const byte) init_irq::toSpritePtr2_return#0
[18] (byte) irq_cnt#11 ← (byte/signed byte/word/signed word/dword/signed dword) 0
asm { sei }
[13] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0
[14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127
[15] *((const byte*) RASTER#0) ← (const byte) IRQ_RASTER_FIRST#0
[16] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0
[17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq()
[20] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0
[21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127
[22] *((const byte*) RASTER#0) ← (const byte) IRQ_RASTER_FIRST#0
[23] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0
[24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq()
asm { cli }
to:init_irq::@return
init_irq::@return: scope:[init_irq] from init_irq
[19] return
init_irq::@return: scope:[init_irq] from init_irq::@1
[26] return
to:@return
init_sprites: scope:[init_sprites] from main
[20] phi()
[27] phi()
to:init_sprites::vicSelectGfxBank1
init_sprites::vicSelectGfxBank1: scope:[init_sprites] from init_sprites
[21] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3
[28] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3
to:init_sprites::vicSelectGfxBank1_toDd001
init_sprites::vicSelectGfxBank1_toDd001: scope:[init_sprites] from init_sprites::vicSelectGfxBank1
[22] phi()
[29] phi()
to:init_sprites::vicSelectGfxBank1_@1
init_sprites::vicSelectGfxBank1_@1: scope:[init_sprites] from init_sprites::vicSelectGfxBank1_toDd001
[23] *((const byte*) CIA2_PORT_A#0) ← (const byte) init_sprites::vicSelectGfxBank1_toDd001_return#0
[30] *((const byte*) CIA2_PORT_A#0) ← (const byte) init_sprites::vicSelectGfxBank1_toDd001_return#0
to:init_sprites::toD0181
init_sprites::toD0181: scope:[init_sprites] from init_sprites::vicSelectGfxBank1_@1
[24] phi()
[31] phi()
to:init_sprites::@4
init_sprites::@4: scope:[init_sprites] from init_sprites::toD0181
[25] *((const byte*) D018#0) ← (const byte) init_sprites::toD0181_return#0
[26] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15
[27] *((const byte*) SPRITES_MC#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
[28] *((const byte*) SPRITES_EXPAND_Y#0) ← *((const byte*) SPRITES_MC#0)
[29] *((const byte*) SPRITES_EXPAND_X#0) ← *((const byte*) SPRITES_EXPAND_Y#0)
to:init_sprites::toSpritePtr1
init_sprites::toSpritePtr1: scope:[init_sprites] from init_sprites::@4
[30] phi()
[32] *((const byte*) D018#0) ← (const byte) init_sprites::toD0181_return#0
[33] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15
[34] *((const byte*) SPRITES_MC#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
[35] *((const byte*) SPRITES_EXPAND_Y#0) ← *((const byte*) SPRITES_MC#0)
[36] *((const byte*) SPRITES_EXPAND_X#0) ← *((const byte*) SPRITES_EXPAND_Y#0)
to:init_sprites::@1
init_sprites::@1: scope:[init_sprites] from init_sprites::@1 init_sprites::toSpritePtr1
[31] (byte) init_sprites::ptr#2 ← phi( init_sprites::@1/(byte) init_sprites::ptr#1 init_sprites::toSpritePtr1/(const byte) init_sprites::toSpritePtr1_return#0 )
[31] (byte) init_sprites::xpos#2 ← phi( init_sprites::@1/(byte) init_sprites::xpos#1 init_sprites::toSpritePtr1/(byte/signed byte/word/signed word/dword/signed dword) 24+(byte/signed byte/word/signed word/dword/signed dword) 14*(byte/signed byte/word/signed word/dword/signed dword) 8 )
[31] (byte) init_sprites::s#2 ← phi( init_sprites::@1/(byte) init_sprites::s#1 init_sprites::toSpritePtr1/(byte/signed byte/word/signed word/dword/signed dword) 0 )
[32] (byte) init_sprites::s2#0 ← (byte) init_sprites::s#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
[33] *((const byte*) SPRITES_XPOS#0 + (byte) init_sprites::s2#0) ← (byte) init_sprites::xpos#2
[34] *((const byte*) SPRITES_YPOS#0 + (byte) init_sprites::s2#0) ← (const byte) init_sprites::ypos#0
[35] *((const byte*) SPRITES_COLS#0 + (byte) init_sprites::s#2) ← (const byte) BLACK#0
[36] *((const byte*) init_sprites::sprites_ptr#0 + (byte) init_sprites::s#2) ← (byte) init_sprites::ptr#2
[37] (byte) init_sprites::xpos#1 ← (byte) init_sprites::xpos#2 + (byte/signed byte/word/signed word/dword/signed dword) 24
[38] (byte) init_sprites::ptr#1 ← ++ (byte) init_sprites::ptr#2
[39] (byte) init_sprites::s#1 ← ++ (byte) init_sprites::s#2
[40] if((byte) init_sprites::s#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto init_sprites::@1
init_sprites::@1: scope:[init_sprites] from init_sprites::@1 init_sprites::@4
[37] (byte) init_sprites::xpos#2 ← phi( init_sprites::@1/(byte) init_sprites::xpos#1 init_sprites::@4/(byte/signed byte/word/signed word/dword/signed dword) 24+(byte/signed byte/word/signed word/dword/signed dword) 14*(byte/signed byte/word/signed word/dword/signed dword) 8 )
[37] (byte) init_sprites::s#2 ← phi( init_sprites::@1/(byte) init_sprites::s#1 init_sprites::@4/(byte/signed byte/word/signed word/dword/signed dword) 0 )
[38] (byte) init_sprites::s2#0 ← (byte) init_sprites::s#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
[39] *((const byte*) SPRITES_XPOS#0 + (byte) init_sprites::s2#0) ← (byte) init_sprites::xpos#2
[40] *((const byte*) SPRITES_COLS#0 + (byte) init_sprites::s#2) ← (const byte) BLACK#0
[41] (byte) init_sprites::xpos#1 ← (byte) init_sprites::xpos#2 + (byte/signed byte/word/signed word/dword/signed dword) 24
[42] (byte) init_sprites::s#1 ← ++ (byte) init_sprites::s#2
[43] if((byte) init_sprites::s#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto init_sprites::@1
to:init_sprites::@return
init_sprites::@return: scope:[init_sprites] from init_sprites::@1
[41] return
[44] return
to:@return
irq: scope:[irq] from
[42] *((const byte*) BGCOL#0) ← (const byte) WHITE#0
[43] *((const byte*) BORDERCOL#0) ← *((const byte*) BGCOL#0)
[44] *((const byte*) SPRITES_YPOS#0) ← (byte) irq_sprite_ypos#0
[45] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) irq_sprite_ypos#0
[46] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← (byte) irq_sprite_ypos#0
[47] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) irq_sprite_ypos#0
[48] (byte) irq_cnt#1 ← ++ (byte) irq_cnt#0
[49] if((byte) irq_cnt#1==(byte/signed byte/word/signed word/dword/signed dword) 10) goto irq::@1
[45] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0
[46] *((const byte*) SPRITES_YPOS#0) ← (byte) irq_sprite_ypos#2
[47] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) irq_sprite_ypos#2
[48] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← (byte) irq_sprite_ypos#2
[49] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) irq_sprite_ypos#2
to:irq::@1
irq::@1: scope:[irq] from irq irq::@1
[50] if(*((const byte*) RASTER#0)!=(byte) irq_sprite_ypos#2) goto irq::@1
to:irq::@4
irq::@4: scope:[irq] from irq::@1
[51] (byte) irq::ptr#0 ← (byte) irq_sprite_ptr#2
[52] *((const byte*) PLAYFIELD_SPRITE_PTRS#0) ← (byte) irq::ptr#0
[53] (byte) irq::ptr#1 ← ++ (byte) irq::ptr#0
[54] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) irq::ptr#1
[55] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) irq::ptr#1
[56] (byte) irq::ptr#2 ← ++ (byte) irq::ptr#1
[57] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) irq::ptr#2
[58] (byte) irq_cnt#23 ← ++ (byte) irq_cnt#19
[59] if((byte) irq_cnt#23==(byte/signed byte/word/signed word/dword/signed dword) 10) goto irq::@2
to:irq::@5
irq::@5: scope:[irq] from irq::@4
[60] (byte) irq_raster_next#6 ← (byte) irq_raster_next#2 + (byte/signed byte/word/signed word/dword/signed dword) 21
[61] (byte) irq_sprite_ypos#6 ← (byte) irq_sprite_ypos#2 + (byte/signed byte/word/signed word/dword/signed dword) 21
[62] (byte) irq_sprite_ptr#6 ← (byte) irq_sprite_ptr#2 + (byte/signed byte/word/signed word/dword/signed dword) 3
to:irq::@3
irq::@3: scope:[irq] from irq
[50] (byte) irq_raster_next#2 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21
[51] (byte) irq_sprite_ypos#2 ← (byte) irq_sprite_ypos#0 + (byte/signed byte/word/signed word/dword/signed dword) 21
to:irq::@2
irq::@2: scope:[irq] from irq::@1 irq::@3
[52] (byte) irq_raster_next#3 ← phi( irq::@1/(byte) irq_raster_next#1 irq::@3/(byte) irq_raster_next#2 )
[53] *((const byte*) RASTER#0) ← (byte) irq_raster_next#3
[54] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0
[55] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0
[56] *((const byte*) BGCOL#0) ← (const byte) BLUE#0
irq::@3: scope:[irq] from irq::@5 irq::@7
[63] (byte) irq_raster_next#13 ← phi( irq::@5/(byte) irq_raster_next#6 irq::@7/(byte) irq_raster_next#20 )
[64] *((const byte*) RASTER#0) ← (byte) irq_raster_next#13
[65] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0
[66] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0
to:irq::@return
irq::@return: scope:[irq] from irq::@2
[57] return
irq::@return: scope:[irq] from irq::@3
[67] return
to:@return
irq::@1: scope:[irq] from irq
[58] (byte) irq_cnt#2 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[59] (byte) irq_raster_next#1 ← (const byte) IRQ_RASTER_FIRST#0
[60] (byte) irq_sprite_ypos#1 ← (byte/signed byte/word/signed word/dword/signed dword) 50
to:irq::@2
irq::@2: scope:[irq] from irq::@4
[68] (byte) irq_cnt#24 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[69] (byte) irq_raster_next#20 ← (const byte) IRQ_RASTER_FIRST#0
[70] (byte) irq_sprite_ypos#26 ← (byte/signed byte/word/signed word/dword/signed dword) 50
to:irq::toSpritePtr2
irq::toSpritePtr2: scope:[irq] from irq::@2
[71] phi()
to:irq::@7
irq::@7: scope:[irq] from irq::toSpritePtr2
[72] (byte) irq_sprite_ptr#5 ← (const byte) irq::toSpritePtr2_return#0
to:irq::@3

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
(label) @6
(label) @8
(label) @9
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53281
(byte*) BGCOL1
(byte*) BGCOL2
(byte*) BGCOL3
@ -11,7 +11,6 @@
(byte) BLACK
(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0
(byte) BLUE
(const byte) BLUE#0 BLUE = (byte/signed byte/word/signed word/dword/signed dword) 6
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53280
(byte) BROWN
@ -38,6 +37,7 @@
(byte*) D018
(const byte*) D018#0 D018 = ((byte*))(word/dword/signed dword) 53272
(byte) DARK_GREY
(const byte) DARK_GREY#0 DARK_GREY = (byte/signed byte/word/signed word/dword/signed dword) 11
(byte) GREEN
(byte) GREY
(void()**) HARDWARE_IRQ
@ -67,6 +67,8 @@
(const byte*) PLAYFIELD_SCREEN#0 PLAYFIELD_SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
(byte*) PLAYFIELD_SPRITES
(const byte*) PLAYFIELD_SPRITES#0 PLAYFIELD_SPRITES = ((byte*))(word/signed word/dword/signed dword) 8192
(byte*) PLAYFIELD_SPRITE_PTRS
(const byte*) PLAYFIELD_SPRITE_PTRS#0 PLAYFIELD_SPRITE_PTRS = (const byte*) PLAYFIELD_SCREEN#0+(const word) SPRITE_PTRS#0
(byte*) PROCPORT
(byte) PROCPORT_BASIC_KERNEL_IO
(byte*) PROCPORT_DDR
@ -111,24 +113,26 @@
(byte) VIC_RSEL
(byte) VIC_RST8
(byte) WHITE
(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) YELLOW
(void()) init_irq()
(label) init_irq::@1
(label) init_irq::@return
(label) init_irq::toSpritePtr2
(word~) init_irq::toSpritePtr2_$0
(word~) init_irq::toSpritePtr2_$1
(byte~) init_irq::toSpritePtr2_$2
(byte) init_irq::toSpritePtr2_return
(const byte) init_irq::toSpritePtr2_return#0 toSpritePtr2_return = ((byte))((word))(const byte*) PLAYFIELD_SPRITES#0>>(byte/signed byte/word/signed word/dword/signed dword) 6
(byte*) init_irq::toSpritePtr2_sprite
(void()) init_sprites()
(label) init_sprites::@1
(label) init_sprites::@4
(label) init_sprites::@return
(byte) init_sprites::ptr
(byte) init_sprites::ptr#1 ptr zp ZP_BYTE:3 7.333333333333333
(byte) init_sprites::ptr#2 ptr zp ZP_BYTE:3 4.714285714285714
(byte) init_sprites::s
(byte) init_sprites::s#1 reg byte y 16.5
(byte) init_sprites::s#2 reg byte y 6.875
(byte) init_sprites::s#1 reg byte x 16.5
(byte) init_sprites::s#2 reg byte x 8.8
(byte) init_sprites::s2
(byte) init_sprites::s2#0 reg byte x 16.5
(byte*) init_sprites::sprites_ptr
(const byte*) init_sprites::sprites_ptr#0 sprites_ptr = (const byte*) PLAYFIELD_SCREEN#0+(const word) SPRITE_PTRS#0
(byte) init_sprites::s2#0 reg byte a 22.0
(label) init_sprites::toD0181
(word~) init_sprites::toD0181_$0
(word~) init_sprites::toD0181_$1
@ -143,13 +147,6 @@
(byte) init_sprites::toD0181_return
(const byte) init_sprites::toD0181_return#0 toD0181_return = >((word))(const byte*) PLAYFIELD_SCREEN#0&(word/signed word/dword/signed dword) 16383<<(byte/signed byte/word/signed word/dword/signed dword) 2|>((word))(const byte*) PLAYFIELD_CHARSET#0>>(byte/signed byte/word/signed word/dword/signed dword) 2&(byte/signed byte/word/signed word/dword/signed dword) 15
(byte*) init_sprites::toD0181_screen
(label) init_sprites::toSpritePtr1
(word~) init_sprites::toSpritePtr1_$0
(word~) init_sprites::toSpritePtr1_$1
(byte~) init_sprites::toSpritePtr1_$2
(byte) init_sprites::toSpritePtr1_return
(const byte) init_sprites::toSpritePtr1_return#0 toSpritePtr1_return = ((byte))((word))(const byte*) PLAYFIELD_SPRITES#0>>(byte/signed byte/word/signed word/dword/signed dword) 6
(byte*) init_sprites::toSpritePtr1_sprite
(label) init_sprites::vicSelectGfxBank1
(byte~) init_sprites::vicSelectGfxBank1_$0
(label) init_sprites::vicSelectGfxBank1_@1
@ -163,33 +160,62 @@
(byte) init_sprites::vicSelectGfxBank1_toDd001_return
(const byte) init_sprites::vicSelectGfxBank1_toDd001_return#0 vicSelectGfxBank1_toDd001_return = (byte/signed byte/word/signed word/dword/signed dword) 3^>((word))(const byte*) PLAYFIELD_SCREEN#0>>(byte/signed byte/word/signed word/dword/signed dword) 6
(byte) init_sprites::xpos
(byte) init_sprites::xpos#1 xpos zp ZP_BYTE:2 5.5
(byte) init_sprites::xpos#2 xpos zp ZP_BYTE:2 5.5
(byte) init_sprites::ypos
(const byte) init_sprites::ypos#0 ypos = (byte/signed byte/word/signed word/dword/signed dword) 50
(byte) init_sprites::xpos#1 xpos zp ZP_BYTE:2 7.333333333333333
(byte) init_sprites::xpos#2 xpos zp ZP_BYTE:2 8.25
interrupt(KERNEL_MIN)(void()) irq()
(label) irq::@1
(label) irq::@2
(label) irq::@3
(label) irq::@4
(label) irq::@5
(label) irq::@7
(label) irq::@return
(byte) irq::ptr
(byte) irq::ptr#0 reg byte x 3.0
(byte) irq::ptr#1 reg byte x 2.6666666666666665
(byte) irq::ptr#2 reg byte x 4.0
(label) irq::toSpritePtr2
(word~) irq::toSpritePtr2_$0
(word~) irq::toSpritePtr2_$1
(byte~) irq::toSpritePtr2_$2
(byte) irq::toSpritePtr2_return
(const byte) irq::toSpritePtr2_return#0 toSpritePtr2_return = ((byte))((word))(const byte*) PLAYFIELD_SPRITES#0>>(byte/signed byte/word/signed word/dword/signed dword) 6
(byte*) irq::toSpritePtr2_sprite
(byte) irq_cnt
(byte) irq_cnt#0 irq_cnt zp ZP_BYTE:2 0.6666666666666666
(byte) irq_cnt#1 irq_cnt zp ZP_BYTE:2 4.0
(byte) irq_cnt#2 irq_cnt zp ZP_BYTE:2 20.0
(byte) irq_cnt#11 irq_cnt zp ZP_BYTE:2 20.0
(byte) irq_cnt#19 irq_cnt zp ZP_BYTE:2 0.3076923076923077
(byte) irq_cnt#23 irq_cnt zp ZP_BYTE:2 4.0
(byte) irq_cnt#24 irq_cnt zp ZP_BYTE:2 20.0
(byte) irq_raster_next
(byte) irq_raster_next#0 irq_raster_next zp ZP_BYTE:2 0.5
(byte) irq_raster_next#1 irq_raster_next zp ZP_BYTE:2 2.0
(byte) irq_raster_next#2 irq_raster_next zp ZP_BYTE:2 2.0
(byte) irq_raster_next#3 irq_raster_next zp ZP_BYTE:2 6.0
(byte) irq_raster_next#11 irq_raster_next zp ZP_BYTE:2 20.0
(byte) irq_raster_next#13 irq_raster_next zp ZP_BYTE:2 6.0
(byte) irq_raster_next#2 irq_raster_next zp ZP_BYTE:2 0.26666666666666666
(byte) irq_raster_next#20 irq_raster_next zp ZP_BYTE:2 1.0
(byte) irq_raster_next#6 irq_raster_next zp ZP_BYTE:2 1.3333333333333333
(byte) irq_sprite_ptr
(byte) irq_sprite_ptr#2 irq_sprite_ptr zp ZP_BYTE:2 0.3529411764705882
(byte) irq_sprite_ptr#3 irq_sprite_ptr zp ZP_BYTE:2 20.0
(byte) irq_sprite_ptr#5 irq_sprite_ptr zp ZP_BYTE:2 20.0
(byte) irq_sprite_ptr#6 irq_sprite_ptr zp ZP_BYTE:2 20.0
(byte) irq_sprite_ypos
(byte) irq_sprite_ypos#0 irq_sprite_ypos zp ZP_BYTE:2 1.3333333333333335
(byte) irq_sprite_ypos#1 irq_sprite_ypos zp ZP_BYTE:2 20.0
(byte) irq_sprite_ypos#2 irq_sprite_ypos zp ZP_BYTE:2 20.0
(byte) irq_sprite_ypos#11 irq_sprite_ypos zp ZP_BYTE:2 20.0
(byte) irq_sprite_ypos#2 irq_sprite_ypos zp ZP_BYTE:2 1.4375
(byte) irq_sprite_ypos#26 irq_sprite_ypos zp ZP_BYTE:2 20.0
(byte) irq_sprite_ypos#6 irq_sprite_ypos zp ZP_BYTE:2 20.0
(void()) main()
(label) main::@1
(label) main::@return
(label) main::@2
(label) main::@7
(label) toSpritePtr1
(word~) toSpritePtr1_$0
(word~) toSpritePtr1_$1
(byte~) toSpritePtr1_$2
(byte) toSpritePtr1_return
(const byte) toSpritePtr1_return#0 toSpritePtr1_return = ((byte))((word))(const byte*) PLAYFIELD_SPRITES#0>>(byte/signed byte/word/signed word/dword/signed dword) 6
(byte*) toSpritePtr1_sprite
reg byte y [ init_sprites::s#2 init_sprites::s#1 ]
zp ZP_BYTE:2 [ init_sprites::xpos#2 init_sprites::xpos#1 irq_raster_next#3 irq_raster_next#1 irq_raster_next#2 irq_raster_next#0 irq_cnt#0 irq_cnt#1 irq_sprite_ypos#0 irq_sprite_ypos#2 irq_cnt#2 irq_sprite_ypos#1 ]
zp ZP_BYTE:3 [ init_sprites::ptr#2 init_sprites::ptr#1 ]
reg byte x [ init_sprites::s2#0 ]
reg byte x [ init_sprites::s#2 init_sprites::s#1 ]
zp ZP_BYTE:2 [ init_sprites::xpos#2 init_sprites::xpos#1 irq_raster_next#13 irq_raster_next#6 irq_raster_next#20 irq_raster_next#2 irq_sprite_ypos#2 irq_sprite_ypos#6 irq_sprite_ptr#2 irq_sprite_ptr#6 irq_cnt#19 irq_cnt#23 irq_raster_next#11 irq_sprite_ypos#11 irq_sprite_ptr#3 irq_cnt#11 irq_cnt#24 irq_sprite_ypos#26 irq_sprite_ptr#5 ]
reg byte a [ init_sprites::s2#0 ]
reg byte x [ irq::ptr#0 ]
reg byte x [ irq::ptr#1 ]
reg byte x [ irq::ptr#2 ]

View File

@ -0,0 +1,17 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label x = 2
lda #$c
sta x
jsr main
main: {
b1:
inc x
lda x
cmp #$32
bcc b1
lda #0
sta x
rts
}

View File

@ -0,0 +1,23 @@
@begin: scope:[] from
[0] (byte) x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[5] (byte) x#5 ← phi( main/(byte) x#0 main::@1/(byte) x#1 )
[6] (byte) x#1 ← ++ (byte) x#5
[7] if((byte) x#1<(byte/signed byte/word/signed word/dword/signed dword) 50) goto main::@1
to:main::@3
main::@3: scope:[main] from main::@1
[8] (byte) x#2 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@return
main::@return: scope:[main] from main::@3
[9] return
to:@return

View File

@ -0,0 +1,337 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte) x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12
to:@1
main: scope:[main] from @1
(byte) x#8 ← phi( @1/(byte) x#10 )
to:main::@1
main::@1: scope:[main] from main main::@2
(byte) x#5 ← phi( main/(byte) x#8 main::@2/(byte) x#9 )
(byte) x#1 ← ++ (byte) x#5
(bool~) main::$0 ← (byte) x#1 < (byte/signed byte/word/signed word/dword/signed dword) 50
if((bool~) main::$0) goto main::@2
to:main::@3
main::@2: scope:[main] from main::@1
(byte) x#9 ← phi( main::@1/(byte) x#1 )
to:main::@1
main::@3: scope:[main] from main::@1
(byte) x#2 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@return
main::@return: scope:[main] from main::@3
(byte) x#6 ← phi( main::@3/(byte) x#2 )
(byte) x#3 ← (byte) x#6
return
to:@return
@1: scope:[] from @begin
(byte) x#10 ← phi( @begin/(byte) x#0 )
call main
to:@2
@2: scope:[] from @1
(byte) x#7 ← phi( @1/(byte) x#3 )
(byte) x#4 ← (byte) x#7
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(void()) main()
(bool~) main::$0
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(byte) x
(byte) x#0
(byte) x#1
(byte) x#10
(byte) x#2
(byte) x#3
(byte) x#4
(byte) x#5
(byte) x#6
(byte) x#7
(byte) x#8
(byte) x#9
Alias (byte) x#1 = (byte) x#9
Alias (byte) x#2 = (byte) x#6 (byte) x#3
Alias (byte) x#0 = (byte) x#10
Alias (byte) x#4 = (byte) x#7
Successful SSA optimization Pass2AliasElimination
Redundant Phi (byte) x#8 (byte) x#0
Redundant Phi (byte) x#4 (byte) x#2
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) main::$0 if((byte) x#1<(byte/signed byte/word/signed word/dword/signed dword) 50) goto main::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Culled Empty Block (label) main::@2
Culled Empty Block (label) @2
Successful SSA optimization Pass2CullEmptyBlocks
Added new block during phi lifting main::@7(between main::@1 and main::@1)
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Created 1 initial phi equivalence classes
Coalesced [4] x#11 ← x#0
Coalesced [10] x#12 ← x#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) main::@7
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] (byte) x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[5] (byte) x#5 ← phi( main/(byte) x#0 main::@1/(byte) x#1 )
[6] (byte) x#1 ← ++ (byte) x#5
[7] if((byte) x#1<(byte/signed byte/word/signed word/dword/signed dword) 50) goto main::@1
to:main::@3
main::@3: scope:[main] from main::@1
[8] (byte) x#2 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@return
main::@return: scope:[main] from main::@3
[9] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
(byte) x
(byte) x#0 1.3333333333333333
(byte) x#1 16.5
(byte) x#2 20.0
(byte) x#5 24.0
Initial phi equivalence classes
[ x#5 x#0 x#1 ]
Added variable x#2 to zero page equivalence class [ x#2 ]
Complete equivalence classes
[ x#5 x#0 x#1 ]
[ x#2 ]
Allocated zp ZP_BYTE:2 [ x#5 x#0 x#1 ]
Allocated zp ZP_BYTE:3 [ x#2 ]
INITIAL ASM
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label x = 2
.label x_2 = 3
//SEG2 @begin
bbegin:
//SEG3 [0] (byte) x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12 -- vbuz1=vbuc1
lda #$c
sta x
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG5 @1
b1:
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG9 @end
bend:
//SEG10 main
main: {
//SEG11 [5] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1]
b1_from_main:
b1_from_b1:
//SEG12 [5] phi (byte) x#5 = (byte) x#0 [phi:main/main::@1->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) x#1 ← ++ (byte) x#5 -- vbuz1=_inc_vbuz1
inc x
//SEG15 [7] if((byte) x#1<(byte/signed byte/word/signed word/dword/signed dword) 50) goto main::@1 -- vbuz1_lt_vbuc1_then_la1
lda x
cmp #$32
bcc b1_from_b1
jmp b3
//SEG16 main::@3
b3:
//SEG17 [8] (byte) x#2 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta x_2
jmp breturn
//SEG18 main::@return
breturn:
//SEG19 [9] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte) x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12 [ x#0 ] ( ) always clobbers reg byte a
Statement [7] if((byte) x#1<(byte/signed byte/word/signed word/dword/signed dword) 50) goto main::@1 [ x#1 ] ( main:2 [ x#1 ] ) always clobbers reg byte a
Statement [8] (byte) x#2 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:2 [ x#5 x#0 x#1 ] : zp ZP_BYTE:2 ,
Potential registers zp ZP_BYTE:3 [ x#2 ] : zp ZP_BYTE:3 ,
REGISTER UPLIFT SCOPES
Uplift Scope [] 41.83: zp ZP_BYTE:2 [ x#5 x#0 x#1 ] 20: zp ZP_BYTE:3 [ x#2 ]
Uplift Scope [main]
Uplifting [] best 216 combination zp ZP_BYTE:2 [ x#5 x#0 x#1 ] zp ZP_BYTE:3 [ x#2 ]
Uplifting [main] best 216 combination
Attempting to uplift remaining variables inzp ZP_BYTE:2 [ x#5 x#0 x#1 ]
Uplifting [] best 216 combination zp ZP_BYTE:2 [ x#5 x#0 x#1 ]
Attempting to uplift remaining variables inzp ZP_BYTE:3 [ x#2 ]
Uplifting [] best 216 combination zp ZP_BYTE:3 [ x#2 ]
Coalescing zero page register [ zp ZP_BYTE:2 [ x#5 x#0 x#1 ] ] with [ zp ZP_BYTE:3 [ x#2 ] ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label x = 2
//SEG2 @begin
bbegin:
//SEG3 [0] (byte) x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12 -- vbuz1=vbuc1
lda #$c
sta x
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG5 @1
b1:
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG9 @end
bend:
//SEG10 main
main: {
//SEG11 [5] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1]
b1_from_main:
b1_from_b1:
//SEG12 [5] phi (byte) x#5 = (byte) x#0 [phi:main/main::@1->main::@1#0] -- register_copy
jmp b1
//SEG13 main::@1
b1:
//SEG14 [6] (byte) x#1 ← ++ (byte) x#5 -- vbuz1=_inc_vbuz1
inc x
//SEG15 [7] if((byte) x#1<(byte/signed byte/word/signed word/dword/signed dword) 50) goto main::@1 -- vbuz1_lt_vbuc1_then_la1
lda x
cmp #$32
bcc b1_from_b1
jmp b3
//SEG16 main::@3
b3:
//SEG17 [8] (byte) x#2 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta x
jmp breturn
//SEG18 main::@return
breturn:
//SEG19 [9] return
rts
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b3
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b1 with b1
Removing instruction b1_from_bbegin:
Removing instruction main_from_b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_main:
Removing instruction b1_from_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bbegin:
Removing instruction b1:
Removing instruction bend:
Removing instruction b3:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(void()) main()
(label) main::@1
(label) main::@3
(label) main::@return
(byte) x
(byte) x#0 x zp ZP_BYTE:2 1.3333333333333333
(byte) x#1 x zp ZP_BYTE:2 16.5
(byte) x#2 x zp ZP_BYTE:2 20.0
(byte) x#5 x zp ZP_BYTE:2 24.0
zp ZP_BYTE:2 [ x#5 x#0 x#1 x#2 ]
FINAL ASSEMBLER
Score: 147
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label x = 2
//SEG2 @begin
//SEG3 [0] (byte) x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12 -- vbuz1=vbuc1
lda #$c
sta x
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
//SEG5 @1
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
jsr main
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
//SEG9 @end
//SEG10 main
main: {
//SEG11 [5] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1]
//SEG12 [5] phi (byte) x#5 = (byte) x#0 [phi:main/main::@1->main::@1#0] -- register_copy
//SEG13 main::@1
b1:
//SEG14 [6] (byte) x#1 ← ++ (byte) x#5 -- vbuz1=_inc_vbuz1
inc x
//SEG15 [7] if((byte) x#1<(byte/signed byte/word/signed word/dword/signed dword) 50) goto main::@1 -- vbuz1_lt_vbuc1_then_la1
lda x
cmp #$32
bcc b1
//SEG16 main::@3
//SEG17 [8] (byte) x#2 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta x
//SEG18 main::@return
//SEG19 [9] return
rts
}

View File

@ -0,0 +1,14 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(label) main::@1
(label) main::@3
(label) main::@return
(byte) x
(byte) x#0 x zp ZP_BYTE:2 1.3333333333333333
(byte) x#1 x zp ZP_BYTE:2 16.5
(byte) x#2 x zp ZP_BYTE:2 20.0
(byte) x#5 x zp ZP_BYTE:2 24.0
zp ZP_BYTE:2 [ x#5 x#0 x#1 x#2 ]

View File

@ -0,0 +1,53 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label KERNEL_IRQ = $314
.label BORDERCOL = $d021
.label BGCOL = $d020
.label col1 = 2
.label col2 = 2
lda #0
sta col1
lda #8
sta col2
jsr main
main: {
.label SCREEN = $400
.label row = 2
.label asd = 3
lda #0
sta asd
ldx #$20
tay
lda #$c
sta row
b1:
inc row
lda row
sta SCREEN,y
inx
txa
clc
adc asd
sta asd
iny
cpy #$b
bne b1
stx SCREEN
sta SCREEN+1
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
rts
}
irq: {
lda $dc0d
lda col1
sta BGCOL
inc col1
lda col2
sta BORDERCOL
inc col2
jmp $ea81
}

View File

@ -0,0 +1,43 @@
@begin: scope:[] from
[0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
to:@2
@2: scope:[] from @begin
[2] phi()
[3] call main
to:@end
@end: scope:[] from @2
[4] phi()
main: scope:[main] from @2
[5] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[6] (byte) main::asd#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::asd#1 )
[6] (byte) main::qwe#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 32 main::@1/(byte) main::qwe#1 )
[6] (byte) main::x#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::x#1 )
[6] (byte) main::row#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 12 main::@1/(byte) main::row#1 )
[7] (byte) main::row#1 ← ++ (byte) main::row#2
[8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1
[9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2
[10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1
[11] (byte) main::x#1 ← ++ (byte) main::x#2
[12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1
[13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1
[14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1
[15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq()
to:main::@return
main::@return: scope:[main] from main::@2
[16] return
to:@return
irq: scope:[irq] from
asm { lda$dc0d }
[18] *((const byte*) BGCOL#0) ← (byte) col1#0
[19] (byte) col1#1 ← ++ (byte) col1#0
[20] *((const byte*) BORDERCOL#0) ← (byte) col2#0
[21] (byte) col2#1 ← ++ (byte) col2#0
to:irq::@return
irq::@return: scope:[irq] from irq
[22] return
to:@return

View File

@ -0,0 +1,775 @@
Resolved forward reference irq to interrupt(KERNEL_MIN)(void()) irq()
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788
(byte*) BORDERCOL#0 ← ((byte*)) (word/dword/signed dword) 53281
(byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) 53280
(byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
to:@2
main: scope:[main] from @2
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) 1024
(byte) main::qwe#0 ← (byte/signed byte/word/signed word/dword/signed dword) 32
(byte) main::asd#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(byte) main::row#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12
(byte) main::x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@1
(byte) main::asd#2 ← phi( main/(byte) main::asd#0 main::@1/(byte) main::asd#1 )
(byte) main::qwe#2 ← phi( main/(byte) main::qwe#0 main::@1/(byte) main::qwe#1 )
(byte) main::x#2 ← phi( main/(byte) main::x#0 main::@1/(byte) main::x#1 )
(byte*) main::SCREEN#1 ← phi( main/(byte*) main::SCREEN#0 main::@1/(byte*) main::SCREEN#1 )
(byte) main::row#2 ← phi( main/(byte) main::row#0 main::@1/(byte) main::row#1 )
(byte) main::row#1 ← ++ (byte) main::row#2
*((byte*) main::SCREEN#1 + (byte) main::x#2) ← (byte) main::row#1
(byte) main::qwe#1 ← ++ (byte) main::qwe#2
(byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1
(byte) main::x#1 ← (byte) main::x#2 + rangenext(0,10)
(bool~) main::$0 ← (byte) main::x#1 != rangelast(0,10)
if((bool~) main::$0) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1
(byte) main::asd#3 ← phi( main::@1/(byte) main::asd#1 )
(byte*) main::SCREEN#2 ← phi( main::@1/(byte*) main::SCREEN#1 )
(byte) main::qwe#3 ← phi( main::@1/(byte) main::qwe#1 )
*((byte*) main::SCREEN#2 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← (byte) main::qwe#3
*((byte*) main::SCREEN#2 + (byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#3
(void()*~) main::$1 ← & interrupt(KERNEL_MIN)(void()) irq()
*((void()**) KERNEL_IRQ#0) ← (void()*~) main::$1
to:main::@return
main::@return: scope:[main] from main::@2
return
to:@return
irq: scope:[irq] from
(byte) col2#3 ← phi( @2/(byte) col2#5 )
(byte) col1#3 ← phi( @2/(byte) col1#5 )
asm { lda$dc0d }
*((byte*) BGCOL#0) ← (byte) col1#3
(byte) col1#1 ← ++ (byte) col1#3
*((byte*) BORDERCOL#0) ← (byte) col2#3
(byte) col2#1 ← ++ (byte) col2#3
to:irq::@return
irq::@return: scope:[irq] from irq
(byte) col2#4 ← phi( irq/(byte) col2#1 )
(byte) col1#4 ← phi( irq/(byte) col1#1 )
(byte) col1#2 ← (byte) col1#4
(byte) col2#2 ← (byte) col2#4
return
to:@return
@2: scope:[] from @begin
(byte) col2#5 ← phi( @begin/(byte) col2#0 )
(byte) col1#5 ← phi( @begin/(byte) col1#0 )
call main
to:@3
@3: scope:[] from @2
to:@end
@end: scope:[] from @3
SYMBOL TABLE SSA
(label) @2
(label) @3
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL#0
(byte*) BORDERCOL
(byte*) BORDERCOL#0
(void()**) KERNEL_IRQ
(void()**) KERNEL_IRQ#0
(byte) col1
(byte) col1#0
(byte) col1#1
(byte) col1#2
(byte) col1#3
(byte) col1#4
(byte) col1#5
(byte) col2
(byte) col2#0
(byte) col2#1
(byte) col2#2
(byte) col2#3
(byte) col2#4
(byte) col2#5
interrupt(KERNEL_MIN)(void()) irq()
(label) irq::@return
(void()) main()
(bool~) main::$0
(void()*~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(byte*) main::SCREEN#0
(byte*) main::SCREEN#1
(byte*) main::SCREEN#2
(byte) main::asd
(byte) main::asd#0
(byte) main::asd#1
(byte) main::asd#2
(byte) main::asd#3
(byte) main::qwe
(byte) main::qwe#0
(byte) main::qwe#1
(byte) main::qwe#2
(byte) main::qwe#3
(byte) main::row
(byte) main::row#0
(byte) main::row#1
(byte) main::row#2
(byte) main::x
(byte) main::x#0
(byte) main::x#1
(byte) main::x#2
Culled Empty Block (label) @3
Successful SSA optimization Pass2CullEmptyBlocks
Alias (byte) main::qwe#1 = (byte) main::qwe#3
Alias (byte*) main::SCREEN#1 = (byte*) main::SCREEN#2
Alias (byte) main::asd#1 = (byte) main::asd#3
Alias (byte) col1#1 = (byte) col1#4 (byte) col1#2
Alias (byte) col2#1 = (byte) col2#4 (byte) col2#2
Alias (byte) col1#0 = (byte) col1#5
Alias (byte) col2#0 = (byte) col2#5
Successful SSA optimization Pass2AliasElimination
Self Phi Eliminated (byte*) main::SCREEN#1
Successful SSA optimization Pass2SelfPhiElimination
Redundant Phi (byte*) main::SCREEN#1 (byte*) main::SCREEN#0
Redundant Phi (byte) col1#3 (byte) col1#0
Redundant Phi (byte) col2#3 (byte) col2#0
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) main::$0 if((byte) main::x#1!=rangelast(0,10)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788
Constant (const byte*) BORDERCOL#0 = ((byte*))53281
Constant (const byte*) BGCOL#0 = ((byte*))53280
Constant (const byte*) main::SCREEN#0 = ((byte*))1024
Constant (const byte) main::qwe#0 = 32
Constant (const byte) main::asd#0 = 0
Constant (const byte) main::row#0 = 12
Constant (const byte) main::x#0 = 0
Constant (const void()*) main::$1 = &irq
Successful SSA optimization Pass2ConstantIdentification
Consolidated array index constant in *(main::SCREEN#0+0)
Consolidated array index constant in *(main::SCREEN#0+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Resolved ranged next value main::x#1 ← ++ main::x#2 to ++
Resolved ranged comparison value if(main::x#1!=rangelast(0,10)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 11
Inlining constant with var siblings (const byte) main::qwe#0
Inlining constant with var siblings (const byte) main::asd#0
Inlining constant with var siblings (const byte) main::row#0
Inlining constant with var siblings (const byte) main::x#0
Constant inlined main::qwe#0 = (byte/signed byte/word/signed word/dword/signed dword) 32
Constant inlined main::x#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::asd#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$1 = &interrupt(KERNEL_MIN)(void()) irq()
Constant inlined main::row#0 = (byte/signed byte/word/signed word/dword/signed dword) 12
Successful SSA optimization Pass2ConstantInlining
Simplifying constant plus zero main::SCREEN#0+0
Added new block during phi lifting main::@3(between main::@1 and main::@1)
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
CALL GRAPH
Calls in [] to main:3
Created 4 initial phi equivalence classes
Coalesced [17] main::row#3 ← main::row#1
Coalesced [18] main::x#3 ← main::x#1
Coalesced [19] main::qwe#4 ← main::qwe#1
Coalesced [20] main::asd#4 ← main::asd#1
Coalesced down to 4 phi equivalence classes
Culled Empty Block (label) main::@3
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
to:@2
@2: scope:[] from @begin
[2] phi()
[3] call main
to:@end
@end: scope:[] from @2
[4] phi()
main: scope:[main] from @2
[5] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[6] (byte) main::asd#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::asd#1 )
[6] (byte) main::qwe#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 32 main::@1/(byte) main::qwe#1 )
[6] (byte) main::x#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::x#1 )
[6] (byte) main::row#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 12 main::@1/(byte) main::row#1 )
[7] (byte) main::row#1 ← ++ (byte) main::row#2
[8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1
[9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2
[10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1
[11] (byte) main::x#1 ← ++ (byte) main::x#2
[12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1
[13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1
[14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1
[15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq()
to:main::@return
main::@return: scope:[main] from main::@2
[16] return
to:@return
irq: scope:[irq] from
asm { lda$dc0d }
[18] *((const byte*) BGCOL#0) ← (byte) col1#0
[19] (byte) col1#1 ← ++ (byte) col1#0
[20] *((const byte*) BORDERCOL#0) ← (byte) col2#0
[21] (byte) col2#1 ← ++ (byte) col2#0
to:irq::@return
irq::@return: scope:[irq] from irq
[22] return
to:@return
VARIABLE REGISTER WEIGHTS
(byte*) BGCOL
(byte*) BORDERCOL
(void()**) KERNEL_IRQ
(byte) col1
(byte) col1#0 3.0
(byte) col1#1 20.0
(byte) col2
(byte) col2#0 1.5
(byte) col2#1 20.0
interrupt(KERNEL_MIN)(void()) irq()
(void()) main()
(byte*) main::SCREEN
(byte) main::asd
(byte) main::asd#1 6.0
(byte) main::asd#2 5.5
(byte) main::qwe
(byte) main::qwe#1 8.75
(byte) main::qwe#2 7.333333333333333
(byte) main::row
(byte) main::row#1 5.5
(byte) main::row#2 22.0
(byte) main::x
(byte) main::x#1 16.5
(byte) main::x#2 6.6000000000000005
Initial phi equivalence classes
[ main::row#2 main::row#1 ]
[ main::x#2 main::x#1 ]
[ main::qwe#2 main::qwe#1 ]
[ main::asd#2 main::asd#1 ]
Added variable col1#0 to zero page equivalence class [ col1#0 ]
Added variable col2#0 to zero page equivalence class [ col2#0 ]
Added variable col1#1 to zero page equivalence class [ col1#1 ]
Added variable col2#1 to zero page equivalence class [ col2#1 ]
Complete equivalence classes
[ main::row#2 main::row#1 ]
[ main::x#2 main::x#1 ]
[ main::qwe#2 main::qwe#1 ]
[ main::asd#2 main::asd#1 ]
[ col1#0 ]
[ col2#0 ]
[ col1#1 ]
[ col2#1 ]
Allocated zp ZP_BYTE:2 [ main::row#2 main::row#1 ]
Allocated zp ZP_BYTE:3 [ main::x#2 main::x#1 ]
Allocated zp ZP_BYTE:4 [ main::qwe#2 main::qwe#1 ]
Allocated zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ]
Allocated zp ZP_BYTE:6 [ col1#0 ]
Allocated zp ZP_BYTE:7 [ col2#0 ]
Allocated zp ZP_BYTE:8 [ col1#1 ]
Allocated zp ZP_BYTE:9 [ col2#1 ]
INITIAL ASM
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label BORDERCOL = $d021
.label BGCOL = $d020
.label col1 = 6
.label col2 = 7
.label col1_1 = 8
.label col2_1 = 9
//SEG2 @begin
bbegin:
//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta col1
//SEG4 [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuz1=vbuc1
lda #8
sta col2
//SEG5 [2] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
jmp b2
//SEG6 @2
b2:
//SEG7 [3] call main
//SEG8 [5] phi from @2 to main [phi:@2->main]
main_from_b2:
jsr main
//SEG9 [4] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
jmp bend
//SEG10 @end
bend:
//SEG11 main
main: {
.label SCREEN = $400
.label row = 2
.label qwe = 4
.label asd = 5
.label x = 3
//SEG12 [6] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
//SEG13 [6] phi (byte) main::asd#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta asd
//SEG14 [6] phi (byte) main::qwe#2 = (byte/signed byte/word/signed word/dword/signed dword) 32 [phi:main->main::@1#1] -- vbuz1=vbuc1
lda #$20
sta qwe
//SEG15 [6] phi (byte) main::x#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#2] -- vbuz1=vbuc1
lda #0
sta x
//SEG16 [6] phi (byte) main::row#2 = (byte/signed byte/word/signed word/dword/signed dword) 12 [phi:main->main::@1#3] -- vbuz1=vbuc1
lda #$c
sta row
jmp b1
//SEG17 [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG18 [6] phi (byte) main::asd#2 = (byte) main::asd#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG19 [6] phi (byte) main::qwe#2 = (byte) main::qwe#1 [phi:main::@1->main::@1#1] -- register_copy
//SEG20 [6] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@1->main::@1#2] -- register_copy
//SEG21 [6] phi (byte) main::row#2 = (byte) main::row#1 [phi:main::@1->main::@1#3] -- register_copy
jmp b1
//SEG22 main::@1
b1:
//SEG23 [7] (byte) main::row#1 ← ++ (byte) main::row#2 -- vbuz1=_inc_vbuz1
inc row
//SEG24 [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 -- pbuc1_derefidx_vbuz1=vbuz2
lda row
ldy x
sta SCREEN,y
//SEG25 [9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2 -- vbuz1=_inc_vbuz1
inc qwe
//SEG26 [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 -- vbuz1=vbuz1_plus_vbuz2
lda asd
clc
adc qwe
sta asd
//SEG27 [11] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuz1=_inc_vbuz1
inc x
//SEG28 [12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda x
cmp #$b
bne b1_from_b1
jmp b2
//SEG29 main::@2
b2:
//SEG30 [13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1 -- _deref_pbuc1=vbuz1
lda qwe
sta SCREEN
//SEG31 [14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1 -- _deref_pbuc1=vbuz1
lda asd
sta SCREEN+1
//SEG32 [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
jmp breturn
//SEG33 main::@return
breturn:
//SEG34 [16] return
rts
}
//SEG35 irq
irq: {
//SEG36 entry interrupt(KERNEL_MIN)
//SEG37 asm { lda$dc0d }
lda $dc0d
//SEG38 [18] *((const byte*) BGCOL#0) ← (byte) col1#0 -- _deref_pbuc1=vbuz1
lda col1
sta BGCOL
//SEG39 [19] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz2
ldy col1
iny
sty col1_1
//SEG40 [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 -- _deref_pbuc1=vbuz1
lda col2
sta BORDERCOL
//SEG41 [21] (byte) col2#1 ← ++ (byte) col2#0 -- vbuz1=_inc_vbuz2
ldy col2
iny
sty col2_1
jmp breturn
//SEG42 irq::@return
breturn:
//SEG43 [22] return - exit interrupt(KERNEL_MIN)
jmp $ea81
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a
Statement [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 [ ] ( ) always clobbers reg byte a
Statement [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ( main:3 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::x#2 main::x#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::row#2 main::row#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ main::qwe#2 main::qwe#1 ]
Statement [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement asm { lda$dc0d } always clobbers reg byte a
Statement [18] *((const byte*) BGCOL#0) ← (byte) col1#0 [ col1#0 col2#0 ] ( ) always clobbers reg byte a
Statement [19] (byte) col1#1 ← ++ (byte) col1#0 [ col2#0 ] ( ) always clobbers reg byte y
Statement [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 [ col2#0 ] ( ) always clobbers reg byte a
Statement [21] (byte) col2#1 ← ++ (byte) col2#0 [ ] ( ) always clobbers reg byte y
Statement [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a
Statement [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 [ ] ( ) always clobbers reg byte a
Statement [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 [ main::x#2 main::qwe#2 main::asd#2 main::row#1 ] ( main:3 [ main::x#2 main::qwe#2 main::asd#2 main::row#1 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ]
Statement [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ( main:3 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ) always clobbers reg byte a
Statement [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement asm { lda$dc0d } always clobbers reg byte a
Statement [18] *((const byte*) BGCOL#0) ← (byte) col1#0 [ col1#0 col2#0 ] ( ) always clobbers reg byte a
Statement [19] (byte) col1#1 ← ++ (byte) col1#0 [ col2#0 ] ( ) always clobbers reg byte y
Statement [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 [ col2#0 ] ( ) always clobbers reg byte a
Statement [21] (byte) col2#1 ← ++ (byte) col2#0 [ ] ( ) always clobbers reg byte y
Statement [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a
Statement [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 [ ] ( ) always clobbers reg byte a
Statement [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 [ main::x#2 main::qwe#2 main::asd#2 main::row#1 ] ( main:3 [ main::x#2 main::qwe#2 main::asd#2 main::row#1 ] ) always clobbers reg byte a
Statement [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ( main:3 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ) always clobbers reg byte a
Statement [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement asm { lda$dc0d } always clobbers reg byte a
Statement [18] *((const byte*) BGCOL#0) ← (byte) col1#0 [ col1#0 col2#0 ] ( ) always clobbers reg byte a
Statement [19] (byte) col1#1 ← ++ (byte) col1#0 [ col2#0 ] ( ) always clobbers reg byte y
Statement [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 [ col2#0 ] ( ) always clobbers reg byte a
Statement [21] (byte) col2#1 ← ++ (byte) col2#0 [ ] ( ) always clobbers reg byte y
Potential registers zp ZP_BYTE:2 [ main::row#2 main::row#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:3 [ main::x#2 main::x#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:4 [ main::qwe#2 main::qwe#1 ] : zp ZP_BYTE:4 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ] : zp ZP_BYTE:5 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:6 [ col1#0 ] : zp ZP_BYTE:6 ,
Potential registers zp ZP_BYTE:7 [ col2#0 ] : zp ZP_BYTE:7 ,
Potential registers zp ZP_BYTE:8 [ col1#1 ] : zp ZP_BYTE:8 ,
Potential registers zp ZP_BYTE:9 [ col2#1 ] : zp ZP_BYTE:9 ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::row#2 main::row#1 ] 23.1: zp ZP_BYTE:3 [ main::x#2 main::x#1 ] 16.08: zp ZP_BYTE:4 [ main::qwe#2 main::qwe#1 ] 11.5: zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ]
Uplift Scope [] 20: zp ZP_BYTE:8 [ col1#1 ] 20: zp ZP_BYTE:9 [ col2#1 ] 3: zp ZP_BYTE:6 [ col1#0 ] 1.5: zp ZP_BYTE:7 [ col2#0 ]
Uplift Scope [irq]
Uplifting [main] best 639 combination zp ZP_BYTE:2 [ main::row#2 main::row#1 ] reg byte y [ main::x#2 main::x#1 ] reg byte x [ main::qwe#2 main::qwe#1 ] zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ]
Uplifting [] best 639 combination zp ZP_BYTE:8 [ col1#1 ] zp ZP_BYTE:9 [ col2#1 ] zp ZP_BYTE:6 [ col1#0 ] zp ZP_BYTE:7 [ col2#0 ]
Uplifting [irq] best 639 combination
Attempting to uplift remaining variables inzp ZP_BYTE:2 [ main::row#2 main::row#1 ]
Uplifting [main] best 639 combination zp ZP_BYTE:2 [ main::row#2 main::row#1 ]
Attempting to uplift remaining variables inzp ZP_BYTE:8 [ col1#1 ]
Uplifting [] best 639 combination zp ZP_BYTE:8 [ col1#1 ]
Attempting to uplift remaining variables inzp ZP_BYTE:9 [ col2#1 ]
Uplifting [] best 639 combination zp ZP_BYTE:9 [ col2#1 ]
Attempting to uplift remaining variables inzp ZP_BYTE:5 [ main::asd#2 main::asd#1 ]
Uplifting [main] best 639 combination zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ]
Attempting to uplift remaining variables inzp ZP_BYTE:6 [ col1#0 ]
Uplifting [] best 639 combination zp ZP_BYTE:6 [ col1#0 ]
Attempting to uplift remaining variables inzp ZP_BYTE:7 [ col2#0 ]
Uplifting [] best 639 combination zp ZP_BYTE:7 [ col2#0 ]
Coalescing zero page register with common assignment [ zp ZP_BYTE:6 [ col1#0 ] ] with [ zp ZP_BYTE:8 [ col1#1 ] ] - score: 1
Coalescing zero page register with common assignment [ zp ZP_BYTE:7 [ col2#0 ] ] with [ zp ZP_BYTE:9 [ col2#1 ] ] - score: 1
Coalescing zero page register [ zp ZP_BYTE:2 [ main::row#2 main::row#1 ] ] with [ zp ZP_BYTE:6 [ col1#0 col1#1 ] ]
Coalescing zero page register [ zp ZP_BYTE:2 [ main::row#2 main::row#1 col1#0 col1#1 ] ] with [ zp ZP_BYTE:7 [ col2#0 col2#1 ] ]
Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:3 [ main::asd#2 main::asd#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label BORDERCOL = $d021
.label BGCOL = $d020
.label col1 = 2
.label col2 = 2
//SEG2 @begin
bbegin:
//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta col1
//SEG4 [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuz1=vbuc1
lda #8
sta col2
//SEG5 [2] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
jmp b2
//SEG6 @2
b2:
//SEG7 [3] call main
//SEG8 [5] phi from @2 to main [phi:@2->main]
main_from_b2:
jsr main
//SEG9 [4] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
jmp bend
//SEG10 @end
bend:
//SEG11 main
main: {
.label SCREEN = $400
.label row = 2
.label asd = 3
//SEG12 [6] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
//SEG13 [6] phi (byte) main::asd#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta asd
//SEG14 [6] phi (byte) main::qwe#2 = (byte/signed byte/word/signed word/dword/signed dword) 32 [phi:main->main::@1#1] -- vbuxx=vbuc1
ldx #$20
//SEG15 [6] phi (byte) main::x#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#2] -- vbuyy=vbuc1
ldy #0
//SEG16 [6] phi (byte) main::row#2 = (byte/signed byte/word/signed word/dword/signed dword) 12 [phi:main->main::@1#3] -- vbuz1=vbuc1
lda #$c
sta row
jmp b1
//SEG17 [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG18 [6] phi (byte) main::asd#2 = (byte) main::asd#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG19 [6] phi (byte) main::qwe#2 = (byte) main::qwe#1 [phi:main::@1->main::@1#1] -- register_copy
//SEG20 [6] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@1->main::@1#2] -- register_copy
//SEG21 [6] phi (byte) main::row#2 = (byte) main::row#1 [phi:main::@1->main::@1#3] -- register_copy
jmp b1
//SEG22 main::@1
b1:
//SEG23 [7] (byte) main::row#1 ← ++ (byte) main::row#2 -- vbuz1=_inc_vbuz1
inc row
//SEG24 [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 -- pbuc1_derefidx_vbuyy=vbuz1
lda row
sta SCREEN,y
//SEG25 [9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2 -- vbuxx=_inc_vbuxx
inx
//SEG26 [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 -- vbuz1=vbuz1_plus_vbuxx
txa
clc
adc asd
sta asd
//SEG27 [11] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuyy=_inc_vbuyy
iny
//SEG28 [12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
cpy #$b
bne b1_from_b1
jmp b2
//SEG29 main::@2
b2:
//SEG30 [13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1 -- _deref_pbuc1=vbuxx
stx SCREEN
//SEG31 [14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1 -- _deref_pbuc1=vbuz1
lda asd
sta SCREEN+1
//SEG32 [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
jmp breturn
//SEG33 main::@return
breturn:
//SEG34 [16] return
rts
}
//SEG35 irq
irq: {
//SEG36 entry interrupt(KERNEL_MIN)
//SEG37 asm { lda$dc0d }
lda $dc0d
//SEG38 [18] *((const byte*) BGCOL#0) ← (byte) col1#0 -- _deref_pbuc1=vbuz1
lda col1
sta BGCOL
//SEG39 [19] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz1
inc col1
//SEG40 [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 -- _deref_pbuc1=vbuz1
lda col2
sta BORDERCOL
//SEG41 [21] (byte) col2#1 ← ++ (byte) col2#0 -- vbuz1=_inc_vbuz1
inc col2
jmp breturn
//SEG42 irq::@return
breturn:
//SEG43 [22] return - exit interrupt(KERNEL_MIN)
jmp $ea81
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b2
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing instruction ldy #0 with TAY
Replacing label b1_from_b1 with b1
Removing instruction b2_from_bbegin:
Removing instruction main_from_b2:
Removing instruction bend_from_b2:
Removing instruction b1_from_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bbegin:
Removing instruction b2:
Removing instruction bend:
Removing instruction b1_from_main:
Removing instruction b2:
Removing instruction breturn:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jmp b1
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda asd
Succesful ASM optimization Pass5UnnecesaryLoadElimination
FINAL SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53281
(void()**) KERNEL_IRQ
(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788
(byte) col1
(byte) col1#0 col1 zp ZP_BYTE:2 3.0
(byte) col1#1 col1 zp ZP_BYTE:2 20.0
(byte) col2
(byte) col2#0 col2 zp ZP_BYTE:2 1.5
(byte) col2#1 col2 zp ZP_BYTE:2 20.0
interrupt(KERNEL_MIN)(void()) irq()
(label) irq::@return
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
(byte) main::asd
(byte) main::asd#1 asd zp ZP_BYTE:3 6.0
(byte) main::asd#2 asd zp ZP_BYTE:3 5.5
(byte) main::qwe
(byte) main::qwe#1 reg byte x 8.75
(byte) main::qwe#2 reg byte x 7.333333333333333
(byte) main::row
(byte) main::row#1 row zp ZP_BYTE:2 5.5
(byte) main::row#2 row zp ZP_BYTE:2 22.0
(byte) main::x
(byte) main::x#1 reg byte y 16.5
(byte) main::x#2 reg byte y 6.6000000000000005
zp ZP_BYTE:2 [ main::row#2 main::row#1 col1#0 col1#1 col2#0 col2#1 ]
reg byte y [ main::x#2 main::x#1 ]
reg byte x [ main::qwe#2 main::qwe#1 ]
zp ZP_BYTE:3 [ main::asd#2 main::asd#1 ]
FINAL ASSEMBLER
Score: 528
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label BORDERCOL = $d021
.label BGCOL = $d020
.label col1 = 2
.label col2 = 2
//SEG2 @begin
//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta col1
//SEG4 [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuz1=vbuc1
lda #8
sta col2
//SEG5 [2] phi from @begin to @2 [phi:@begin->@2]
//SEG6 @2
//SEG7 [3] call main
//SEG8 [5] phi from @2 to main [phi:@2->main]
jsr main
//SEG9 [4] phi from @2 to @end [phi:@2->@end]
//SEG10 @end
//SEG11 main
main: {
.label SCREEN = $400
.label row = 2
.label asd = 3
//SEG12 [6] phi from main to main::@1 [phi:main->main::@1]
//SEG13 [6] phi (byte) main::asd#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta asd
//SEG14 [6] phi (byte) main::qwe#2 = (byte/signed byte/word/signed word/dword/signed dword) 32 [phi:main->main::@1#1] -- vbuxx=vbuc1
ldx #$20
//SEG15 [6] phi (byte) main::x#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#2] -- vbuyy=vbuc1
tay
//SEG16 [6] phi (byte) main::row#2 = (byte/signed byte/word/signed word/dword/signed dword) 12 [phi:main->main::@1#3] -- vbuz1=vbuc1
lda #$c
sta row
//SEG17 [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG18 [6] phi (byte) main::asd#2 = (byte) main::asd#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG19 [6] phi (byte) main::qwe#2 = (byte) main::qwe#1 [phi:main::@1->main::@1#1] -- register_copy
//SEG20 [6] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@1->main::@1#2] -- register_copy
//SEG21 [6] phi (byte) main::row#2 = (byte) main::row#1 [phi:main::@1->main::@1#3] -- register_copy
//SEG22 main::@1
b1:
//SEG23 [7] (byte) main::row#1 ← ++ (byte) main::row#2 -- vbuz1=_inc_vbuz1
inc row
//SEG24 [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 -- pbuc1_derefidx_vbuyy=vbuz1
lda row
sta SCREEN,y
//SEG25 [9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2 -- vbuxx=_inc_vbuxx
inx
//SEG26 [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 -- vbuz1=vbuz1_plus_vbuxx
txa
clc
adc asd
sta asd
//SEG27 [11] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuyy=_inc_vbuyy
iny
//SEG28 [12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
cpy #$b
bne b1
//SEG29 main::@2
//SEG30 [13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1 -- _deref_pbuc1=vbuxx
stx SCREEN
//SEG31 [14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1 -- _deref_pbuc1=vbuz1
sta SCREEN+1
//SEG32 [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
//SEG33 main::@return
//SEG34 [16] return
rts
}
//SEG35 irq
irq: {
//SEG36 entry interrupt(KERNEL_MIN)
//SEG37 asm { lda$dc0d }
lda $dc0d
//SEG38 [18] *((const byte*) BGCOL#0) ← (byte) col1#0 -- _deref_pbuc1=vbuz1
lda col1
sta BGCOL
//SEG39 [19] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz1
inc col1
//SEG40 [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 -- _deref_pbuc1=vbuz1
lda col2
sta BORDERCOL
//SEG41 [21] (byte) col2#1 ← ++ (byte) col2#0 -- vbuz1=_inc_vbuz1
inc col2
//SEG42 irq::@return
//SEG43 [22] return - exit interrupt(KERNEL_MIN)
jmp $ea81
}

View File

@ -0,0 +1,40 @@
(label) @2
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53281
(void()**) KERNEL_IRQ
(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788
(byte) col1
(byte) col1#0 col1 zp ZP_BYTE:2 3.0
(byte) col1#1 col1 zp ZP_BYTE:2 20.0
(byte) col2
(byte) col2#0 col2 zp ZP_BYTE:2 1.5
(byte) col2#1 col2 zp ZP_BYTE:2 20.0
interrupt(KERNEL_MIN)(void()) irq()
(label) irq::@return
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
(byte*) main::SCREEN
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
(byte) main::asd
(byte) main::asd#1 asd zp ZP_BYTE:3 6.0
(byte) main::asd#2 asd zp ZP_BYTE:3 5.5
(byte) main::qwe
(byte) main::qwe#1 reg byte x 8.75
(byte) main::qwe#2 reg byte x 7.333333333333333
(byte) main::row
(byte) main::row#1 row zp ZP_BYTE:2 5.5
(byte) main::row#2 row zp ZP_BYTE:2 22.0
(byte) main::x
(byte) main::x#1 reg byte y 16.5
(byte) main::x#2 reg byte y 6.6000000000000005
zp ZP_BYTE:2 [ main::row#2 main::row#1 col1#0 col1#1 col2#0 col2#1 ]
reg byte y [ main::x#2 main::x#1 ]
reg byte x [ main::qwe#2 main::qwe#1 ]
zp ZP_BYTE:3 [ main::asd#2 main::asd#1 ]