1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-17 16:31:34 +00:00

Added missing call-path to interrupts used during uplift clobber-analysis. Closes #130

This commit is contained in:
jespergravgaard 2018-12-25 21:33:07 +01:00
parent ceb271d021
commit 2b25aec8ee
15 changed files with 1793 additions and 686 deletions

View File

@ -60,6 +60,17 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
LiveRangeVariablesEffective.CallPaths callPaths = procedureCallPaths.get(procedureRef);
if(callPaths == null) {
callPaths = new LiveRangeVariablesEffective.CallPaths(procedureRef);
if(procedure.getInterruptType()!=null) {
// Interrupt is called outside procedure scope - create initial call-path.
ArrayList<CallGraph.CallBlock.Call> rootPath = new ArrayList<>();
ArrayList<VariableRef> rootAlive = new ArrayList<>();
// Initialize with global cross-scope aliases (assumed empty)
Pass2AliasElimination.Aliases rootAliases = new Pass2AliasElimination.Aliases();
LiveRangeVariablesEffective.CallPath rootCallPath = new LiveRangeVariablesEffective.CallPath(rootPath, rootAlive, rootAliases, rootAliases);
callPaths.add(rootCallPath);
}
Collection<CallGraph.CallBlock.Call> callers =
getProgram().getCallGraph().getCallers(procedure.getLabel().getRef());
for(CallGraph.CallBlock.Call caller : callers) {

View File

@ -96,7 +96,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
new Pass4RegistersFinalize(program).allocate(false);
// Apply the uplift combination
combination.allocate(program);
// Check the register allocation for whether a is register being allocated to two variables with overlapping live ranges
// Check the register allocation for whether any register is being allocated to two variables with overlapping live ranges
if(isAllocationOverlapping(program)) {
if(program.getLog().isVerboseUplift()) {
StringBuilder msg = new StringBuilder();
@ -198,7 +198,6 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
* @return true if there is an overlapping register allocation
*/
private static boolean isStatementAllocationOverlapping(Program program, Statement statement) {
ProgramScope programScope = program.getScope();
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = program.getLiveRangeVariablesEffective().getAliveCombinations(statement);
for(LiveRangeVariablesEffective.CallPath callPath : aliveCombinations.getCallPaths().getCallPaths()) {
LinkedHashMap<Registers.Register, LiveRangeEquivalenceClass> usedRegisters = new LinkedHashMap<>();

View File

@ -44,6 +44,11 @@ public class TestPrograms {
AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false);
}
@Test
public void testClobberAProblem() throws IOException, URISyntaxException {
compileAndCompare("clobber-a-problem");
}
@Test
public void testInterruptVolatileReuseProblem2() throws IOException, URISyntaxException {
compileAndCompare("interrupt-volatile-reuse-problem2");

View File

@ -0,0 +1,25 @@
byte* BORDERCOL = $d020;
byte* RASTER = $d012;
byte DARK_GREY = $b;
byte BLACK = 0;
const void()** KERNEL_IRQ = $0314;
void main() {
*KERNEL_IRQ = &irq;
}
volatile byte irq_raster_next = 0;
interrupt(hardware_clobber) void irq() {
*BORDERCOL = DARK_GREY;
irq_raster_next += 21;
// Setup next interrupt
byte raster_next = irq_raster_next;
if((raster_next&7)==0) {
raster_next -=1;
}
*RASTER = raster_next;
*BORDERCOL = BLACK;
}

View File

@ -34,12 +34,12 @@ void init_sprites() {
}
// The line of the first IRQ - 48 is 2 lines before the start of the screen
const byte IRQ_RASTER_FIRST = 48;
const byte IRQ_RASTER_FIRST = 49;
// The raster line of the next IRQ
volatile byte irq_raster_next = IRQ_RASTER_FIRST;
// Y-pos of the sprites on the next IRQ
volatile byte irq_sprite_ypos = 50;
// Y-pos of the sprites on the next IRQ
// Index of the sprites to show on the next IRQ
volatile byte irq_sprite_ptr = toSpritePtr(PLAYFIELD_SPRITES);
// Counting the 10 IRQs
volatile byte irq_cnt = 0;
@ -47,6 +47,13 @@ volatile byte irq_cnt = 0;
// Setup the IRQ
void init_irq() {
asm { sei }
// Acknowledge any IRQ and setup the next one
*IRQ_STATUS = IRQ_RASTER;
asm { lda CIA1_INTERRUPT }
// Disable kernal & basic
*PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK;
*PROCPORT = PROCPORT_RAM_IO;
// Disable CIA 1 Timer IRQ
*CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR;
// Set raster line
@ -55,17 +62,16 @@ void init_irq() {
// Enable Raster Interrupt
*IRQ_ENABLE = IRQ_RASTER;
// Set the IRQ routine
*KERNEL_IRQ = &irq;
*HARDWARE_IRQ = &irq;
asm { cli }
}
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 21 lines from line IRQ_RASTER_FIRST
interrupt(kernel_min) void irq() {
interrupt(hardware_clobber) void irq() {
*BORDERCOL = DARK_GREY;
// Place the sprites
SPRITES_YPOS[0] = irq_sprite_ypos;
SPRITES_YPOS[2] = irq_sprite_ypos;
@ -88,15 +94,19 @@ interrupt(kernel_min) void irq() {
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_ptr += 3;
}
// Setup next interrupt
byte raster_next = irq_raster_next;
if((raster_next&7)==3) {
raster_next -=1;
}
*RASTER = raster_next;
// Acknowledge the IRQ and setup the next one
*RASTER = irq_raster_next;
*IRQ_STATUS = IRQ_RASTER;
*BORDERCOL = BLACK;

View File

@ -0,0 +1,45 @@
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
.label BORDERCOL = $d020
.label RASTER = $d012
.const DARK_GREY = $b
.const BLACK = 0
.label KERNEL_IRQ = $314
.label irq_raster_next = 2
bbegin:
lda #0
sta irq_raster_next
jsr main
main: {
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
rts
}
irq: {
sta rega+1
stx regx+1
lda #DARK_GREY
sta BORDERCOL
lda #$15
clc
adc irq_raster_next
sta irq_raster_next
tax
txa
and #7
cmp #0
bne b1
dex
b1:
stx RASTER
lda #BLACK
sta BORDERCOL
rega:
lda #00
regx:
ldx #00
rti
}

View File

@ -0,0 +1,36 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] (byte) irq_raster_next#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:@2
@2: scope:[] from @1
[2] phi()
[3] call main
to:@end
@end: scope:[] from @2
[4] phi()
main: scope:[main] from @2
[5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq()
to:main::@return
main::@return: scope:[main] from main
[6] return
to:@return
irq: scope:[irq] from
[7] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0
[8] (byte) irq_raster_next#1 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21
[9] (byte) irq::raster_next#0 ← (byte) irq_raster_next#1
[10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7
[11] if((byte~) irq::$0!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto irq::@1
to:irq::@2
irq::@2: scope:[irq] from irq
[12] (byte) irq::raster_next#1 ← (byte) irq::raster_next#0 - (byte/signed byte/word/signed word/dword/signed dword) 1
to:irq::@1
irq::@1: scope:[irq] from irq irq::@2
[13] (byte) irq::raster_next#2 ← phi( irq/(byte) irq::raster_next#0 irq::@2/(byte) irq::raster_next#1 )
[14] *((const byte*) RASTER#0) ← (byte) irq::raster_next#2
[15] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0
to:irq::@return
irq::@return: scope:[irq] from irq::@1
[16] return
to:@return

View File

@ -0,0 +1,632 @@
Resolved forward reference irq to interrupt(HARDWARE_CLOBBER)(void()) irq()
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte*) BORDERCOL#0 ← ((byte*)) (word/dword/signed dword) 53280
(byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) 53266
(byte) DARK_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) 11
(byte) BLACK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788
to:@1
main: scope:[main] from @2
(void()*~) main::$0 ← & interrupt(HARDWARE_CLOBBER)(void()) irq()
*((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0
to:main::@return
main::@return: scope:[main] from main
return
to:@return
@1: scope:[] from @begin
(byte) BLACK#5 ← phi( @begin/(byte) BLACK#0 )
(byte*) RASTER#5 ← phi( @begin/(byte*) RASTER#0 )
(byte*) BORDERCOL#5 ← phi( @begin/(byte*) BORDERCOL#0 )
(byte) DARK_GREY#3 ← phi( @begin/(byte) DARK_GREY#0 )
(byte) irq_raster_next#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:@2
irq: scope:[irq] from
(byte) BLACK#2 ← phi( @2/(byte) BLACK#4 )
(byte*) RASTER#2 ← phi( @2/(byte*) RASTER#4 )
(byte) irq_raster_next#3 ← phi( @2/(byte) irq_raster_next#5 )
(byte*) BORDERCOL#1 ← phi( @2/(byte*) BORDERCOL#3 )
(byte) DARK_GREY#1 ← phi( @2/(byte) DARK_GREY#2 )
*((byte*) BORDERCOL#1) ← (byte) DARK_GREY#1
(byte) irq_raster_next#1 ← (byte) irq_raster_next#3 + (byte/signed byte/word/signed word/dword/signed dword) 21
(byte) irq::raster_next#0 ← (byte) irq_raster_next#1
(byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7
(bool~) irq::$1 ← (byte~) irq::$0 == (byte/signed byte/word/signed word/dword/signed dword) 0
(bool~) irq::$2 ← ! (bool~) irq::$1
if((bool~) irq::$2) goto irq::@1
to:irq::@2
irq::@1: scope:[irq] from irq irq::@2
(byte) irq_raster_next#6 ← phi( irq/(byte) irq_raster_next#1 irq::@2/(byte) irq_raster_next#7 )
(byte*) BORDERCOL#2 ← phi( irq/(byte*) BORDERCOL#1 irq::@2/(byte*) BORDERCOL#4 )
(byte) BLACK#1 ← phi( irq/(byte) BLACK#2 irq::@2/(byte) BLACK#3 )
(byte*) RASTER#1 ← phi( irq/(byte*) RASTER#2 irq::@2/(byte*) RASTER#3 )
(byte) irq::raster_next#2 ← phi( irq/(byte) irq::raster_next#0 irq::@2/(byte) irq::raster_next#1 )
*((byte*) RASTER#1) ← (byte) irq::raster_next#2
*((byte*) BORDERCOL#2) ← (byte) BLACK#1
to:irq::@return
irq::@2: scope:[irq] from irq
(byte) irq_raster_next#7 ← phi( irq/(byte) irq_raster_next#1 )
(byte*) BORDERCOL#4 ← phi( irq/(byte*) BORDERCOL#1 )
(byte) BLACK#3 ← phi( irq/(byte) BLACK#2 )
(byte*) RASTER#3 ← phi( irq/(byte*) RASTER#2 )
(byte) irq::raster_next#3 ← phi( irq/(byte) irq::raster_next#0 )
(byte) irq::raster_next#1 ← (byte) irq::raster_next#3 - (byte/signed byte/word/signed word/dword/signed dword) 1
to:irq::@1
irq::@return: scope:[irq] from irq::@1
(byte) irq_raster_next#4 ← phi( irq::@1/(byte) irq_raster_next#6 )
(byte) irq_raster_next#2 ← (byte) irq_raster_next#4
return
to:@return
@2: scope:[] from @1
(byte) BLACK#4 ← phi( @1/(byte) BLACK#5 )
(byte*) RASTER#4 ← phi( @1/(byte*) RASTER#5 )
(byte) irq_raster_next#5 ← phi( @1/(byte) irq_raster_next#0 )
(byte*) BORDERCOL#3 ← phi( @1/(byte*) BORDERCOL#5 )
(byte) DARK_GREY#2 ← phi( @1/(byte) DARK_GREY#3 )
call main
to:@3
@3: scope:[] from @2
to:@end
@end: scope:[] from @3
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(byte) BLACK
(byte) BLACK#0
(byte) BLACK#1
(byte) BLACK#2
(byte) BLACK#3
(byte) BLACK#4
(byte) BLACK#5
(byte*) BORDERCOL
(byte*) BORDERCOL#0
(byte*) BORDERCOL#1
(byte*) BORDERCOL#2
(byte*) BORDERCOL#3
(byte*) BORDERCOL#4
(byte*) BORDERCOL#5
(byte) DARK_GREY
(byte) DARK_GREY#0
(byte) DARK_GREY#1
(byte) DARK_GREY#2
(byte) DARK_GREY#3
(void()**) KERNEL_IRQ
(void()**) KERNEL_IRQ#0
(byte*) RASTER
(byte*) RASTER#0
(byte*) RASTER#1
(byte*) RASTER#2
(byte*) RASTER#3
(byte*) RASTER#4
(byte*) RASTER#5
interrupt(HARDWARE_CLOBBER)(void()) irq()
(byte~) irq::$0
(bool~) irq::$1
(bool~) irq::$2
(label) irq::@1
(label) irq::@2
(label) irq::@return
(byte) irq::raster_next
(byte) irq::raster_next#0
(byte) irq::raster_next#1
(byte) irq::raster_next#2
(byte) irq::raster_next#3
(byte) irq_raster_next
(byte) irq_raster_next#0
(byte) irq_raster_next#1
(byte) irq_raster_next#2
(byte) irq_raster_next#3
(byte) irq_raster_next#4
(byte) irq_raster_next#5
(byte) irq_raster_next#6
(byte) irq_raster_next#7
(void()) main()
(void()*~) main::$0
(label) main::@return
Culled Empty Block (label) @3
Successful SSA optimization Pass2CullEmptyBlocks
Inversing boolean not (bool~) irq::$2 ← (byte~) irq::$0 != (byte/signed byte/word/signed word/dword/signed dword) 0 from (bool~) irq::$1 ← (byte~) irq::$0 == (byte/signed byte/word/signed word/dword/signed dword) 0
Successful SSA optimization Pass2UnaryNotSimplification
Alias (byte) DARK_GREY#0 = (byte) DARK_GREY#3 (byte) DARK_GREY#2
Alias (byte*) BORDERCOL#0 = (byte*) BORDERCOL#5 (byte*) BORDERCOL#3
Alias (byte*) RASTER#0 = (byte*) RASTER#5 (byte*) RASTER#4
Alias (byte) BLACK#0 = (byte) BLACK#5 (byte) BLACK#4
Alias (byte) irq::raster_next#0 = (byte) irq::raster_next#3
Alias (byte*) RASTER#2 = (byte*) RASTER#3
Alias (byte) BLACK#2 = (byte) BLACK#3
Alias (byte*) BORDERCOL#1 = (byte*) BORDERCOL#4
Alias (byte) irq_raster_next#1 = (byte) irq_raster_next#7
Alias (byte) irq_raster_next#2 = (byte) irq_raster_next#4 (byte) irq_raster_next#6
Alias (byte) irq_raster_next#0 = (byte) irq_raster_next#5
Successful SSA optimization Pass2AliasElimination
Alias (byte*) RASTER#1 = (byte*) RASTER#2
Alias (byte) BLACK#1 = (byte) BLACK#2
Alias (byte*) BORDERCOL#1 = (byte*) BORDERCOL#2
Alias (byte) irq_raster_next#1 = (byte) irq_raster_next#2
Successful SSA optimization Pass2AliasElimination
Redundant Phi (byte) DARK_GREY#1 (byte) DARK_GREY#0
Redundant Phi (byte*) BORDERCOL#1 (byte*) BORDERCOL#0
Redundant Phi (byte) irq_raster_next#3 (byte) irq_raster_next#0
Redundant Phi (byte*) RASTER#1 (byte*) RASTER#0
Redundant Phi (byte) BLACK#1 (byte) BLACK#0
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) irq::$2 if((byte~) irq::$0!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto irq::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) BORDERCOL#0 = ((byte*))53280
Constant (const byte*) RASTER#0 = ((byte*))53266
Constant (const byte) DARK_GREY#0 = 11
Constant (const byte) BLACK#0 = 0
Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788
Constant (const void()*) main::$0 = &irq
Successful SSA optimization Pass2ConstantIdentification
Constant inlined main::$0 = &interrupt(HARDWARE_CLOBBER)(void()) irq()
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting irq::@3(between irq and irq::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:3
Created 1 initial phi equivalence classes
Coalesced [13] irq::raster_next#5 ← irq::raster_next#1
Coalesced [18] irq::raster_next#4 ← irq::raster_next#0
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) irq::@3
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] (byte) irq_raster_next#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:@2
@2: scope:[] from @1
[2] phi()
[3] call main
to:@end
@end: scope:[] from @2
[4] phi()
main: scope:[main] from @2
[5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq()
to:main::@return
main::@return: scope:[main] from main
[6] return
to:@return
irq: scope:[irq] from
[7] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0
[8] (byte) irq_raster_next#1 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21
[9] (byte) irq::raster_next#0 ← (byte) irq_raster_next#1
[10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7
[11] if((byte~) irq::$0!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto irq::@1
to:irq::@2
irq::@2: scope:[irq] from irq
[12] (byte) irq::raster_next#1 ← (byte) irq::raster_next#0 - (byte/signed byte/word/signed word/dword/signed dword) 1
to:irq::@1
irq::@1: scope:[irq] from irq irq::@2
[13] (byte) irq::raster_next#2 ← phi( irq/(byte) irq::raster_next#0 irq::@2/(byte) irq::raster_next#1 )
[14] *((const byte*) RASTER#0) ← (byte) irq::raster_next#2
[15] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0
to:irq::@return
irq::@return: scope:[irq] from irq::@1
[16] return
to:@return
VARIABLE REGISTER WEIGHTS
(byte) BLACK
(byte*) BORDERCOL
(byte) DARK_GREY
(void()**) KERNEL_IRQ
(byte*) RASTER
interrupt(HARDWARE_CLOBBER)(void()) irq()
(byte~) irq::$0 4.0
(byte) irq::raster_next
(byte) irq::raster_next#0 2.6666666666666665
(byte) irq::raster_next#1 4.0
(byte) irq::raster_next#2 6.0
(byte) irq_raster_next
(byte) irq_raster_next#0 4.0
(byte) irq_raster_next#1 4.0
(void()) main()
Initial phi equivalence classes
[ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ]
Added variable irq_raster_next#0 to zero page equivalence class [ irq_raster_next#0 ]
Added variable irq_raster_next#1 to zero page equivalence class [ irq_raster_next#1 ]
Added variable irq::$0 to zero page equivalence class [ irq::$0 ]
Complete equivalence classes
[ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ]
[ irq_raster_next#0 ]
[ irq_raster_next#1 ]
[ irq::$0 ]
Allocated zp ZP_BYTE:2 [ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ]
Allocated zp ZP_BYTE:3 [ irq_raster_next#0 ]
Allocated zp ZP_BYTE:4 [ irq_raster_next#1 ]
Allocated zp ZP_BYTE:5 [ irq::$0 ]
INITIAL ASM
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label BORDERCOL = $d020
.label RASTER = $d012
.const DARK_GREY = $b
.const BLACK = 0
.label KERNEL_IRQ = $314
.label irq_raster_next = 3
.label irq_raster_next_1 = 4
//SEG2 @begin
bbegin:
jmp b1
//SEG3 @1
b1:
//SEG4 [1] (byte) irq_raster_next#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta irq_raster_next
//SEG5 [2] phi from @1 to @2 [phi:@1->@2]
b2_from_b1:
jmp b2
//SEG6 @2
b2:
//SEG7 [3] call main
jsr main
//SEG8 [4] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
jmp bend
//SEG9 @end
bend:
//SEG10 main
main: {
//SEG11 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
jmp breturn
//SEG12 main::@return
breturn:
//SEG13 [6] return
rts
}
//SEG14 irq
irq: {
.label _0 = 5
.label raster_next = 2
//SEG15 entry interrupt(HARDWARE_CLOBBER)
sta rega+1
stx regx+1
sty regy+1
//SEG16 [7] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0 -- _deref_pbuc1=vbuc2
lda #DARK_GREY
sta BORDERCOL
//SEG17 [8] (byte) irq_raster_next#1 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21 -- vbuz1=vbuz2_plus_vbuc1
lda #$15
clc
adc irq_raster_next
sta irq_raster_next_1
//SEG18 [9] (byte) irq::raster_next#0 ← (byte) irq_raster_next#1 -- vbuz1=vbuz2
lda irq_raster_next_1
sta raster_next
//SEG19 [10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuz1=vbuz2_band_vbuc1
lda #7
and raster_next
sta _0
//SEG20 [11] if((byte~) irq::$0!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto irq::@1 -- vbuz1_neq_0_then_la1
lda _0
cmp #0
bne b1_from_irq
jmp b2
//SEG21 irq::@2
b2:
//SEG22 [12] (byte) irq::raster_next#1 ← (byte) irq::raster_next#0 - (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuz1=vbuz1_minus_1
dec raster_next
//SEG23 [13] phi from irq irq::@2 to irq::@1 [phi:irq/irq::@2->irq::@1]
b1_from_irq:
b1_from_b2:
//SEG24 [13] phi (byte) irq::raster_next#2 = (byte) irq::raster_next#0 [phi:irq/irq::@2->irq::@1#0] -- register_copy
jmp b1
//SEG25 irq::@1
b1:
//SEG26 [14] *((const byte*) RASTER#0) ← (byte) irq::raster_next#2 -- _deref_pbuc1=vbuz1
lda raster_next
sta RASTER
//SEG27 [15] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
lda #BLACK
sta BORDERCOL
jmp breturn
//SEG28 irq::@return
breturn:
//SEG29 [16] return - exit interrupt(HARDWARE_CLOBBER)
rega:
lda #00
regx:
ldx #00
regy:
ldy #00
rti
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] (byte) irq_raster_next#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a
Statement [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0 [ irq_raster_next#0 ] ( [ irq_raster_next#0 ] ) always clobbers reg byte a
Statement [8] (byte) irq_raster_next#1 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21 [ irq_raster_next#1 ] ( [ irq_raster_next#1 ] ) always clobbers reg byte a
Statement [10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 [ irq::raster_next#0 irq::$0 ] ( [ irq::raster_next#0 irq::$0 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ]
Statement [15] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0 [ ] ( [ ] ) always clobbers reg byte a
Statement [16] return [ ] ( [ ] ) always clobbers reg byte a reg byte x reg byte y
Statement [1] (byte) irq_raster_next#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a
Statement [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0 [ irq_raster_next#0 ] ( [ irq_raster_next#0 ] ) always clobbers reg byte a
Statement [8] (byte) irq_raster_next#1 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21 [ irq_raster_next#1 ] ( [ irq_raster_next#1 ] ) always clobbers reg byte a
Statement [10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 [ irq::raster_next#0 irq::$0 ] ( [ irq::raster_next#0 irq::$0 ] ) always clobbers reg byte a
Statement [15] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0 [ ] ( [ ] ) always clobbers reg byte a
Statement [16] return [ ] ( [ ] ) always clobbers reg byte a reg byte x reg byte y
Potential registers zp ZP_BYTE:2 [ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:3 [ irq_raster_next#0 ] : zp ZP_BYTE:3 ,
Potential registers zp ZP_BYTE:4 [ irq_raster_next#1 ] : zp ZP_BYTE:4 ,
Potential registers zp ZP_BYTE:5 [ irq::$0 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [irq] 12.67: zp ZP_BYTE:2 [ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ] 4: zp ZP_BYTE:5 [ irq::$0 ]
Uplift Scope [] 4: zp ZP_BYTE:3 [ irq_raster_next#0 ] 4: zp ZP_BYTE:4 [ irq_raster_next#1 ]
Uplift Scope [main]
Uplifting [irq] best 248 combination reg byte x [ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ] reg byte a [ irq::$0 ]
Uplifting [] best 248 combination zp ZP_BYTE:3 [ irq_raster_next#0 ] zp ZP_BYTE:4 [ irq_raster_next#1 ]
Uplifting [main] best 248 combination
Attempting to uplift remaining variables inzp ZP_BYTE:3 [ irq_raster_next#0 ]
Uplifting [] best 248 combination zp ZP_BYTE:3 [ irq_raster_next#0 ]
Attempting to uplift remaining variables inzp ZP_BYTE:4 [ irq_raster_next#1 ]
Uplifting [] best 248 combination zp ZP_BYTE:4 [ irq_raster_next#1 ]
Coalescing zero page register with common assignment [ zp ZP_BYTE:3 [ irq_raster_next#0 ] ] with [ zp ZP_BYTE:4 [ irq_raster_next#1 ] ] - score: 1
Allocated (was zp ZP_BYTE:3) zp ZP_BYTE:2 [ irq_raster_next#0 irq_raster_next#1 ]
Interrupt procedure irq clobbers AXCNZV
Removing interrupt register storage sty regy+1 in SEG15 entry interrupt(HARDWARE_CLOBBER)
Removing interrupt register storage regy: in SEG29 [16] return - exit interrupt(HARDWARE_CLOBBER)
Removing interrupt register storage ldy #00 in SEG29 [16] return - exit interrupt(HARDWARE_CLOBBER)
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label BORDERCOL = $d020
.label RASTER = $d012
.const DARK_GREY = $b
.const BLACK = 0
.label KERNEL_IRQ = $314
.label irq_raster_next = 2
//SEG2 @begin
bbegin:
jmp b1
//SEG3 @1
b1:
//SEG4 [1] (byte) irq_raster_next#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta irq_raster_next
//SEG5 [2] phi from @1 to @2 [phi:@1->@2]
b2_from_b1:
jmp b2
//SEG6 @2
b2:
//SEG7 [3] call main
jsr main
//SEG8 [4] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
jmp bend
//SEG9 @end
bend:
//SEG10 main
main: {
//SEG11 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
jmp breturn
//SEG12 main::@return
breturn:
//SEG13 [6] return
rts
}
//SEG14 irq
irq: {
//SEG15 entry interrupt(HARDWARE_CLOBBER)
sta rega+1
stx regx+1
//SEG16 [7] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0 -- _deref_pbuc1=vbuc2
lda #DARK_GREY
sta BORDERCOL
//SEG17 [8] (byte) irq_raster_next#1 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21 -- vbuz1=vbuz1_plus_vbuc1
lda #$15
clc
adc irq_raster_next
sta irq_raster_next
//SEG18 [9] (byte) irq::raster_next#0 ← (byte) irq_raster_next#1 -- vbuxx=vbuz1
ldx irq_raster_next
//SEG19 [10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuaa=vbuxx_band_vbuc1
txa
and #7
//SEG20 [11] if((byte~) irq::$0!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto irq::@1 -- vbuaa_neq_0_then_la1
cmp #0
bne b1_from_irq
jmp b2
//SEG21 irq::@2
b2:
//SEG22 [12] (byte) irq::raster_next#1 ← (byte) irq::raster_next#0 - (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuxx=vbuxx_minus_1
dex
//SEG23 [13] phi from irq irq::@2 to irq::@1 [phi:irq/irq::@2->irq::@1]
b1_from_irq:
b1_from_b2:
//SEG24 [13] phi (byte) irq::raster_next#2 = (byte) irq::raster_next#0 [phi:irq/irq::@2->irq::@1#0] -- register_copy
jmp b1
//SEG25 irq::@1
b1:
//SEG26 [14] *((const byte*) RASTER#0) ← (byte) irq::raster_next#2 -- _deref_pbuc1=vbuxx
stx RASTER
//SEG27 [15] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
lda #BLACK
sta BORDERCOL
jmp breturn
//SEG28 irq::@return
breturn:
//SEG29 [16] return - exit interrupt(HARDWARE_CLOBBER)
rega:
lda #00
regx:
ldx #00
rti
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp bend
Removing instruction jmp breturn
Removing instruction jmp b2
Removing instruction jmp b1
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing instruction ldx irq_raster_next with TAX
Replacing label b1_from_irq with b1
Removing instruction b1:
Removing instruction b2_from_b1:
Removing instruction bend_from_b2:
Removing instruction b1_from_irq:
Removing instruction b1_from_b2:
Removing instruction breturn:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b2:
Removing instruction bend:
Removing instruction breturn:
Removing instruction b2:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @2
(label) @begin
(label) @end
(byte) BLACK
(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53280
(byte) DARK_GREY
(const byte) DARK_GREY#0 DARK_GREY = (byte/signed byte/word/signed word/dword/signed dword) 11
(void()**) KERNEL_IRQ
(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788
(byte*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266
interrupt(HARDWARE_CLOBBER)(void()) irq()
(byte~) irq::$0 reg byte a 4.0
(label) irq::@1
(label) irq::@2
(label) irq::@return
(byte) irq::raster_next
(byte) irq::raster_next#0 reg byte x 2.6666666666666665
(byte) irq::raster_next#1 reg byte x 4.0
(byte) irq::raster_next#2 reg byte x 6.0
(byte) irq_raster_next
(byte) irq_raster_next#0 irq_raster_next zp ZP_BYTE:2 4.0
(byte) irq_raster_next#1 irq_raster_next zp ZP_BYTE:2 4.0
(void()) main()
(label) main::@return
reg byte x [ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ]
zp ZP_BYTE:2 [ irq_raster_next#0 irq_raster_next#1 ]
reg byte a [ irq::$0 ]
FINAL ASSEMBLER
Score: 157
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label BORDERCOL = $d020
.label RASTER = $d012
.const DARK_GREY = $b
.const BLACK = 0
.label KERNEL_IRQ = $314
.label irq_raster_next = 2
//SEG2 @begin
bbegin:
//SEG3 @1
//SEG4 [1] (byte) irq_raster_next#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
lda #0
sta irq_raster_next
//SEG5 [2] phi from @1 to @2 [phi:@1->@2]
//SEG6 @2
//SEG7 [3] call main
jsr main
//SEG8 [4] phi from @2 to @end [phi:@2->@end]
//SEG9 @end
//SEG10 main
main: {
//SEG11 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
//SEG12 main::@return
//SEG13 [6] return
rts
}
//SEG14 irq
irq: {
//SEG15 entry interrupt(HARDWARE_CLOBBER)
sta rega+1
stx regx+1
//SEG16 [7] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0 -- _deref_pbuc1=vbuc2
lda #DARK_GREY
sta BORDERCOL
//SEG17 [8] (byte) irq_raster_next#1 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21 -- vbuz1=vbuz1_plus_vbuc1
lda #$15
clc
adc irq_raster_next
sta irq_raster_next
//SEG18 [9] (byte) irq::raster_next#0 ← (byte) irq_raster_next#1 -- vbuxx=vbuz1
tax
//SEG19 [10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuaa=vbuxx_band_vbuc1
txa
and #7
//SEG20 [11] if((byte~) irq::$0!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto irq::@1 -- vbuaa_neq_0_then_la1
cmp #0
bne b1
//SEG21 irq::@2
//SEG22 [12] (byte) irq::raster_next#1 ← (byte) irq::raster_next#0 - (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuxx=vbuxx_minus_1
dex
//SEG23 [13] phi from irq irq::@2 to irq::@1 [phi:irq/irq::@2->irq::@1]
//SEG24 [13] phi (byte) irq::raster_next#2 = (byte) irq::raster_next#0 [phi:irq/irq::@2->irq::@1#0] -- register_copy
//SEG25 irq::@1
b1:
//SEG26 [14] *((const byte*) RASTER#0) ← (byte) irq::raster_next#2 -- _deref_pbuc1=vbuxx
stx RASTER
//SEG27 [15] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
lda #BLACK
sta BORDERCOL
//SEG28 irq::@return
//SEG29 [16] return - exit interrupt(HARDWARE_CLOBBER)
rega:
lda #00
regx:
ldx #00
rti
}

Binary file not shown.

View File

@ -0,0 +1,32 @@
(label) @1
(label) @2
(label) @begin
(label) @end
(byte) BLACK
(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53280
(byte) DARK_GREY
(const byte) DARK_GREY#0 DARK_GREY = (byte/signed byte/word/signed word/dword/signed dword) 11
(void()**) KERNEL_IRQ
(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788
(byte*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266
interrupt(HARDWARE_CLOBBER)(void()) irq()
(byte~) irq::$0 reg byte a 4.0
(label) irq::@1
(label) irq::@2
(label) irq::@return
(byte) irq::raster_next
(byte) irq::raster_next#0 reg byte x 2.6666666666666665
(byte) irq::raster_next#1 reg byte x 4.0
(byte) irq::raster_next#2 reg byte x 6.0
(byte) irq_raster_next
(byte) irq_raster_next#0 irq_raster_next zp ZP_BYTE:2 4.0
(byte) irq_raster_next#1 irq_raster_next zp ZP_BYTE:2 4.0
(void()) main()
(label) main::@return
reg byte x [ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ]
zp ZP_BYTE:2 [ irq_raster_next#0 irq_raster_next#1 ]
reg byte a [ irq::$0 ]

View File

@ -0,0 +1,11 @@
al C:314 .KERNEL_IRQ
al C:844 .regx
al C:d012 .RASTER
al C:d020 .BORDERCOL
al C:80d .bbegin
al C:842 .rega
al C:81f .irq
al C:80b .upstartEnd
al C:814 .main
al C:2 .irq_raster_next
al C:83a .b1

View File

@ -1,6 +1,10 @@
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
.label PROCPORT_DDR = 0
.const PROCPORT_DDR_MEMORY_MASK = 7
.label PROCPORT = 1
.const PROCPORT_RAM_IO = $35
.const SPRITE_PTRS = $3f8
.label SPRITES_XPOS = $d000
.label SPRITES_YPOS = $d001
@ -20,13 +24,13 @@
.const CIA_INTERRUPT_CLEAR = $7f
.label CIA2_PORT_A = $dd00
.label CIA2_PORT_A_DDR = $dd02
.label KERNEL_IRQ = $314
.label HARDWARE_IRQ = $fffe
.const BLACK = 0
.const DARK_GREY = $b
.label PLAYFIELD_SPRITES = $2000
.label PLAYFIELD_CHARSET = $1000
.label PLAYFIELD_SCREEN = $400
.const IRQ_RASTER_FIRST = $30
.const IRQ_RASTER_FIRST = $31
.label PLAYFIELD_SPRITE_PTRS = PLAYFIELD_SCREEN+SPRITE_PTRS
.const toSpritePtr1_return = PLAYFIELD_SPRITES>>6
.label irq_raster_next = 3
@ -52,6 +56,13 @@ main: {
}
init_irq: {
sei
lda #IRQ_RASTER
sta IRQ_STATUS
lda CIA1_INTERRUPT
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
lda #PROCPORT_RAM_IO
sta PROCPORT
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
lda VIC_CONTROL
@ -62,9 +73,9 @@ init_irq: {
lda #IRQ_RASTER
sta IRQ_ENABLE
lda #<irq
sta KERNEL_IRQ
sta HARDWARE_IRQ
lda #>irq
sta KERNEL_IRQ+1
sta HARDWARE_IRQ+1
cli
rts
}
@ -106,6 +117,8 @@ init_sprites: {
}
irq: {
.const toSpritePtr2_return = PLAYFIELD_SPRITES>>6
sta rega+1
stx regx+1
lda #DARK_GREY
sta BORDERCOL
lda irq_sprite_ypos
@ -120,8 +133,9 @@ irq: {
lda RASTER
cmp irq_sprite_ypos
bne b1
ldx irq_sprite_ptr
stx PLAYFIELD_SPRITE_PTRS
lda irq_sprite_ptr
sta PLAYFIELD_SPRITE_PTRS
tax
inx
stx PLAYFIELD_SPRITE_PTRS+1
stx PLAYFIELD_SPRITE_PTRS+2
@ -144,13 +158,23 @@ irq: {
adc irq_sprite_ptr
sta irq_sprite_ptr
b3:
lda irq_raster_next
sta RASTER
ldx irq_raster_next
txa
and #7
cmp #3
bne b4
dex
b4:
stx RASTER
lda #IRQ_RASTER
sta IRQ_STATUS
lda #BLACK
sta BORDERCOL
jmp $ea81
rega:
lda #00
regx:
ldx #00
rti
b2:
lda #0
sta irq_cnt

View File

@ -42,94 +42,107 @@ main::@2: scope:[main] from main::@2 main::@7
to:main::@2
init_irq: scope:[init_irq] from main::@7
asm { sei }
[15] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0
[16] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127
[17] *((const byte*) RASTER#0) ← (const byte) IRQ_RASTER_FIRST#0
[18] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0
[19] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq()
[15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0
asm { ldaCIA1_INTERRUPT }
[17] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0
[18] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0
[19] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0
[20] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127
[21] *((const byte*) RASTER#0) ← (const byte) IRQ_RASTER_FIRST#0
[22] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0
[23] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq()
asm { cli }
to:init_irq::@return
init_irq::@return: scope:[init_irq] from init_irq
[21] return
[25] return
to:@return
init_sprites: scope:[init_sprites] from main
[22] phi()
[26] phi()
to:init_sprites::vicSelectGfxBank1
init_sprites::vicSelectGfxBank1: scope:[init_sprites] from init_sprites
[23] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3
[27] *((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
[24] phi()
[28] phi()
to:init_sprites::vicSelectGfxBank1_@1
init_sprites::vicSelectGfxBank1_@1: scope:[init_sprites] from init_sprites::vicSelectGfxBank1_toDd001
[25] *((const byte*) CIA2_PORT_A#0) ← (const byte) init_sprites::vicSelectGfxBank1_toDd001_return#0
[29] *((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
[26] phi()
[30] phi()
to:init_sprites::@4
init_sprites::@4: scope:[init_sprites] from init_sprites::toD0181
[27] *((const byte*) D018#0) ← (const byte) init_sprites::toD0181_return#0
[28] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15
[29] *((const byte*) SPRITES_MC#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
[30] *((const byte*) SPRITES_EXPAND_Y#0) ← *((const byte*) SPRITES_MC#0)
[31] *((const byte*) SPRITES_EXPAND_X#0) ← *((const byte*) SPRITES_EXPAND_Y#0)
[31] *((const byte*) D018#0) ← (const byte) init_sprites::toD0181_return#0
[32] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15
[33] *((const byte*) SPRITES_MC#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
[34] *((const byte*) SPRITES_EXPAND_Y#0) ← *((const byte*) SPRITES_MC#0)
[35] *((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::@4
[32] (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 )
[32] (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 )
[33] (byte) init_sprites::s2#0 ← (byte) init_sprites::s#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
[34] *((const byte*) SPRITES_XPOS#0 + (byte) init_sprites::s2#0) ← (byte) init_sprites::xpos#2
[35] *((const byte*) SPRITES_COLS#0 + (byte) init_sprites::s#2) ← (const byte) BLACK#0
[36] (byte) init_sprites::xpos#1 ← (byte) init_sprites::xpos#2 + (byte/signed byte/word/signed word/dword/signed dword) 24
[37] (byte) init_sprites::s#1 ← ++ (byte) init_sprites::s#2
[38] if((byte) init_sprites::s#1!=(byte/signed byte/word/signed word/dword/signed dword) 4) goto init_sprites::@1
[36] (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 )
[36] (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 )
[37] (byte) init_sprites::s2#0 ← (byte) init_sprites::s#2 << (byte/signed byte/word/signed word/dword/signed dword) 1
[38] *((const byte*) SPRITES_XPOS#0 + (byte) init_sprites::s2#0) ← (byte) init_sprites::xpos#2
[39] *((const byte*) SPRITES_COLS#0 + (byte) init_sprites::s#2) ← (const byte) BLACK#0
[40] (byte) init_sprites::xpos#1 ← (byte) init_sprites::xpos#2 + (byte/signed byte/word/signed word/dword/signed dword) 24
[41] (byte) init_sprites::s#1 ← ++ (byte) init_sprites::s#2
[42] 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
[39] return
[43] return
to:@return
irq: scope:[irq] from
[40] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0
[41] *((const byte*) SPRITES_YPOS#0) ← (byte) irq_sprite_ypos#0
[42] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) irq_sprite_ypos#0
[43] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← (byte) irq_sprite_ypos#0
[44] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) irq_sprite_ypos#0
[44] *((const byte*) BORDERCOL#0) ← (const byte) DARK_GREY#0
[45] *((const byte*) SPRITES_YPOS#0) ← (byte) irq_sprite_ypos#0
[46] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) irq_sprite_ypos#0
[47] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← (byte) irq_sprite_ypos#0
[48] *((const byte*) SPRITES_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 6) ← (byte) irq_sprite_ypos#0
to:irq::@1
irq::@1: scope:[irq] from irq irq::@1
[45] if(*((const byte*) RASTER#0)!=(byte) irq_sprite_ypos#0) goto irq::@1
to:irq::@4
irq::@4: scope:[irq] from irq::@1
[46] (byte) irq::ptr#0 ← (byte) irq_sprite_ptr#0
[47] *((const byte*) PLAYFIELD_SPRITE_PTRS#0) ← (byte) irq::ptr#0
[48] (byte) irq::ptr#1 ← ++ (byte) irq::ptr#0
[49] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) irq::ptr#1
[50] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) irq::ptr#1
[51] (byte) irq::ptr#2 ← ++ (byte) irq::ptr#1
[52] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) irq::ptr#2
[53] (byte) irq_cnt#1 ← ++ (byte) irq_cnt#0
[54] if((byte) irq_cnt#1==(byte/signed byte/word/signed word/dword/signed dword) 10) goto irq::@2
[49] if(*((const byte*) RASTER#0)!=(byte) irq_sprite_ypos#0) goto irq::@1
to:irq::@5
irq::@5: scope:[irq] from irq::@4
[55] (byte) irq_raster_next#2 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21
[56] (byte) irq_sprite_ypos#2 ← (byte) irq_sprite_ypos#0 + (byte/signed byte/word/signed word/dword/signed dword) 21
[57] (byte) irq_sprite_ptr#2 ← (byte) irq_sprite_ptr#0 + (byte/signed byte/word/signed word/dword/signed dword) 3
irq::@5: scope:[irq] from irq::@1
[50] (byte) irq::ptr#0 ← (byte) irq_sprite_ptr#0
[51] *((const byte*) PLAYFIELD_SPRITE_PTRS#0) ← (byte) irq::ptr#0
[52] (byte) irq::ptr#1 ← ++ (byte) irq::ptr#0
[53] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) irq::ptr#1
[54] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) irq::ptr#1
[55] (byte) irq::ptr#2 ← ++ (byte) irq::ptr#1
[56] *((const byte*) PLAYFIELD_SPRITE_PTRS#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte) irq::ptr#2
[57] (byte) irq_cnt#1 ← ++ (byte) irq_cnt#0
[58] if((byte) irq_cnt#1==(byte/signed byte/word/signed word/dword/signed dword) 10) goto irq::@2
to:irq::@6
irq::@6: scope:[irq] from irq::@5
[59] (byte) irq_raster_next#2 ← (byte) irq_raster_next#0 + (byte/signed byte/word/signed word/dword/signed dword) 21
[60] (byte) irq_sprite_ypos#2 ← (byte) irq_sprite_ypos#0 + (byte/signed byte/word/signed word/dword/signed dword) 21
[61] (byte) irq_sprite_ptr#2 ← (byte) irq_sprite_ptr#0 + (byte/signed byte/word/signed word/dword/signed dword) 3
to:irq::@3
irq::@3: scope:[irq] from irq::@5 irq::@7
[58] (byte) irq_raster_next#3 ← phi( irq::@5/(byte) irq_raster_next#2 irq::@7/(byte) irq_raster_next#1 )
[59] *((const byte*) RASTER#0) ← (byte) irq_raster_next#3
[60] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0
[61] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0
irq::@3: scope:[irq] from irq::@6 irq::@9
[62] (byte) irq_raster_next#12 ← phi( irq::@6/(byte) irq_raster_next#2 irq::@9/(byte) irq_raster_next#1 )
[63] (byte) irq::raster_next#0 ← (byte) irq_raster_next#12
[64] (byte~) irq::$3 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7
[65] if((byte~) irq::$3!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto irq::@4
to:irq::@8
irq::@8: scope:[irq] from irq::@3
[66] (byte) irq::raster_next#1 ← (byte) irq::raster_next#0 - (byte/signed byte/word/signed word/dword/signed dword) 1
to:irq::@4
irq::@4: scope:[irq] from irq::@3 irq::@8
[67] (byte) irq::raster_next#2 ← phi( irq::@3/(byte) irq::raster_next#0 irq::@8/(byte) irq::raster_next#1 )
[68] *((const byte*) RASTER#0) ← (byte) irq::raster_next#2
[69] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0
[70] *((const byte*) BORDERCOL#0) ← (const byte) BLACK#0
to:irq::@return
irq::@return: scope:[irq] from irq::@3
[62] return
irq::@return: scope:[irq] from irq::@4
[71] return
to:@return
irq::@2: scope:[irq] from irq::@4
[63] (byte) irq_cnt#10 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[64] (byte) irq_raster_next#1 ← (const byte) IRQ_RASTER_FIRST#0
[65] (byte) irq_sprite_ypos#1 ← (byte/signed byte/word/signed word/dword/signed dword) 50
irq::@2: scope:[irq] from irq::@5
[72] (byte) irq_cnt#13 ← (byte/signed byte/word/signed word/dword/signed dword) 0
[73] (byte) irq_raster_next#1 ← (const byte) IRQ_RASTER_FIRST#0
[74] (byte) irq_sprite_ypos#1 ← (byte/signed byte/word/signed word/dword/signed dword) 50
to:irq::toSpritePtr2
irq::toSpritePtr2: scope:[irq] from irq::@2
[66] phi()
to:irq::@7
irq::@7: scope:[irq] from irq::toSpritePtr2
[67] (byte) irq_sprite_ptr#1 ← (const byte) irq::toSpritePtr2_return#0
[75] phi()
to:irq::@9
irq::@9: scope:[irq] from irq::toSpritePtr2
[76] (byte) irq_sprite_ptr#1 ← (const byte) irq::toSpritePtr2_return#0
to:irq::@3

File diff suppressed because it is too large Load Diff

View File

@ -41,6 +41,7 @@
(byte) GREEN
(byte) GREY
(void()**) HARDWARE_IRQ
(const void()**) HARDWARE_IRQ#0 HARDWARE_IRQ = ((void()**))(word/dword/signed dword) 65534
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
@ -49,11 +50,10 @@
(byte) IRQ_RASTER
(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) IRQ_RASTER_FIRST
(const byte) IRQ_RASTER_FIRST#0 IRQ_RASTER_FIRST = (byte/signed byte/word/signed word/dword/signed dword) 48
(const byte) IRQ_RASTER_FIRST#0 IRQ_RASTER_FIRST = (byte/signed byte/word/signed word/dword/signed dword) 49
(byte*) IRQ_STATUS
(const byte*) IRQ_STATUS#0 IRQ_STATUS = ((byte*))(word/dword/signed dword) 53273
(void()**) KERNEL_IRQ
(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_Y
(byte) LIGHT_BLUE
@ -70,13 +70,17 @@
(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
(const byte*) PROCPORT#0 PROCPORT = ((byte*))(byte/signed byte/word/signed word/dword/signed dword) 1
(byte) PROCPORT_BASIC_KERNEL_IO
(byte*) PROCPORT_DDR
(const byte*) PROCPORT_DDR#0 PROCPORT_DDR = ((byte*))(byte/signed byte/word/signed word/dword/signed dword) 0
(byte) PROCPORT_DDR_MEMORY_MASK
(const byte) PROCPORT_DDR_MEMORY_MASK#0 PROCPORT_DDR_MEMORY_MASK = (byte/signed byte/word/signed word/dword/signed dword) 7
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_IO
(const byte) PROCPORT_RAM_IO#0 PROCPORT_RAM_IO = (byte/signed byte/word/signed word/dword/signed dword) 53
(byte) PURPLE
(byte*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266
@ -154,18 +158,25 @@
(byte) init_sprites::xpos
(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()
interrupt(HARDWARE_CLOBBER)(void()) irq()
(byte~) irq::$3 reg byte a 4.0
(label) irq::@1
(label) irq::@2
(label) irq::@3
(label) irq::@4
(label) irq::@5
(label) irq::@7
(label) irq::@6
(label) irq::@8
(label) irq::@9
(label) irq::@return
(byte) irq::ptr
(byte) irq::ptr#0 reg byte x 3.0
(byte) irq::ptr#0 reg byte a 3.0
(byte) irq::ptr#1 reg byte x 2.6666666666666665
(byte) irq::ptr#2 reg byte x 4.0
(byte) irq::raster_next
(byte) irq::raster_next#0 reg byte x 2.6666666666666665
(byte) irq::raster_next#1 reg byte x 4.0
(byte) irq::raster_next#2 reg byte x 6.0
(label) irq::toSpritePtr2
(word~) irq::toSpritePtr2_$0
(word~) irq::toSpritePtr2_$1
@ -176,12 +187,12 @@ interrupt(KERNEL_MIN)(void()) irq()
(byte) irq_cnt
(byte) irq_cnt#0 irq_cnt zp ZP_BYTE:6 0.3076923076923077
(byte) irq_cnt#1 irq_cnt zp ZP_BYTE:6 4.0
(byte) irq_cnt#10 irq_cnt zp ZP_BYTE:6 20.0
(byte) irq_cnt#13 irq_cnt zp ZP_BYTE:6 20.0
(byte) irq_raster_next
(byte) irq_raster_next#0 irq_raster_next zp ZP_BYTE:3 0.26666666666666666
(byte) irq_raster_next#1 irq_raster_next zp ZP_BYTE:3 1.0
(byte) irq_raster_next#12 irq_raster_next zp ZP_BYTE:3 6.0
(byte) irq_raster_next#2 irq_raster_next zp ZP_BYTE:3 1.3333333333333333
(byte) irq_raster_next#3 irq_raster_next zp ZP_BYTE:3 6.0
(byte) irq_sprite_ptr
(byte) irq_sprite_ptr#0 irq_sprite_ptr zp ZP_BYTE:5 0.3529411764705882
(byte) irq_sprite_ptr#1 irq_sprite_ptr zp ZP_BYTE:5 20.0
@ -203,11 +214,13 @@ interrupt(KERNEL_MIN)(void()) irq()
reg byte x [ init_sprites::s#2 init_sprites::s#1 ]
zp ZP_BYTE:2 [ init_sprites::xpos#2 init_sprites::xpos#1 ]
zp ZP_BYTE:3 [ irq_raster_next#3 irq_raster_next#2 irq_raster_next#1 irq_raster_next#0 ]
zp ZP_BYTE:3 [ irq_raster_next#12 irq_raster_next#2 irq_raster_next#1 irq_raster_next#0 ]
reg byte x [ irq::raster_next#2 irq::raster_next#0 irq::raster_next#1 ]
zp ZP_BYTE:4 [ irq_sprite_ypos#0 irq_sprite_ypos#2 irq_sprite_ypos#1 ]
zp ZP_BYTE:5 [ irq_sprite_ptr#0 irq_sprite_ptr#2 irq_sprite_ptr#1 ]
zp ZP_BYTE:6 [ irq_cnt#0 irq_cnt#1 irq_cnt#10 ]
zp ZP_BYTE:6 [ irq_cnt#0 irq_cnt#1 irq_cnt#13 ]
reg byte a [ init_sprites::s2#0 ]
reg byte x [ irq::ptr#0 ]
reg byte a [ irq::ptr#0 ]
reg byte x [ irq::ptr#1 ]
reg byte x [ irq::ptr#2 ]
reg byte a [ irq::$3 ]