From 0ed5059c8a08f914dd3cbd28966529561785da7f Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Fri, 22 May 2020 15:52:51 +0200 Subject: [PATCH] Added support for reserved ZP variables in the target platform .TGT file. Atari 2600 platform file now uses zp range reserving. Closes #447 --- src/main/java/dk/camelot64/kickc/KickC.java | 1 + .../dk/camelot64/kickc/model/Program.java | 4 + .../camelot64/kickc/model/TargetPlatform.java | 11 + .../dk/camelot64/kickc/parser/CParser.java | 5 + .../kickc/parser/CTargetPlatformParser.java | 40 +- src/main/kc/target/atari2600.ld | 1 - src/main/kc/target/atari2600.tgt | 1 + .../dk/camelot64/kickc/test/TestPrograms.java | 1 + .../kc/examples/atari2600/atari2600-demo.c | 10 +- .../kc/examples/atari2600/atari2600-sprites.c | 7 +- .../ref/examples/atari2600/atari2600-demo.asm | 12 +- .../ref/examples/atari2600/atari2600-demo.log | 102 ++-- .../ref/examples/atari2600/atari2600-demo.sym | 6 +- .../examples/atari2600/atari2600-sprites.asm | 48 +- .../examples/atari2600/atari2600-sprites.cfg | 2 +- .../examples/atari2600/atari2600-sprites.log | 456 +++++++++--------- .../examples/atari2600/atari2600-sprites.sym | 20 +- 17 files changed, 398 insertions(+), 329 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/KickC.java b/src/main/java/dk/camelot64/kickc/KickC.java index 1258e0957..bc8578eb0 100644 --- a/src/main/java/dk/camelot64/kickc/KickC.java +++ b/src/main/java/dk/camelot64/kickc/KickC.java @@ -360,6 +360,7 @@ public class KickC implements Callable { effectiveDefines.putAll(defines); if(program.getTargetPlatform().getDefines() != null) effectiveDefines.putAll(program.getTargetPlatform().getDefines()); + program.addReservedZps(program.getTargetPlatform().getReservedZps()); if(preprocess) { System.out.println("Preprocessing " + CFileNames); diff --git a/src/main/java/dk/camelot64/kickc/model/Program.java b/src/main/java/dk/camelot64/kickc/model/Program.java index e3c59358d..ecf0482d5 100644 --- a/src/main/java/dk/camelot64/kickc/model/Program.java +++ b/src/main/java/dk/camelot64/kickc/model/Program.java @@ -491,6 +491,10 @@ public class Program { return reservedZps; } + public void setReservedZps(List reservedZps) { + this.reservedZps = reservedZps; + } + /** * Set the absolute position of the program code * diff --git a/src/main/java/dk/camelot64/kickc/model/TargetPlatform.java b/src/main/java/dk/camelot64/kickc/model/TargetPlatform.java index 1c06c5b90..d89e448ed 100644 --- a/src/main/java/dk/camelot64/kickc/model/TargetPlatform.java +++ b/src/main/java/dk/camelot64/kickc/model/TargetPlatform.java @@ -3,6 +3,8 @@ package dk.camelot64.kickc.model; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; import java.util.Map; /** @@ -34,6 +36,9 @@ public class TargetPlatform { /** A number of preprocessor macro defines. */ private Map defines = null; + /** Reserved zeropage addresses. */ + private List reservedZps = new ArrayList<>(); + public TargetPlatform(String name) { this.name = name; } @@ -99,5 +104,11 @@ public class TargetPlatform { this.defines = defines; } + public void setReservedZps(List reservedZps) { + this.reservedZps = reservedZps; + } + public List getReservedZps() { + return reservedZps; + } } diff --git a/src/main/java/dk/camelot64/kickc/parser/CParser.java b/src/main/java/dk/camelot64/kickc/parser/CParser.java index d8db4f989..6594b50e9 100644 --- a/src/main/java/dk/camelot64/kickc/parser/CParser.java +++ b/src/main/java/dk/camelot64/kickc/parser/CParser.java @@ -235,12 +235,17 @@ public class CParser { if(program.getTargetPlatform() != null && program.getTargetPlatform().getDefines() != null) for(String macroName : program.getTargetPlatform().getDefines().keySet()) preprocessor.undef(macroName); + // Remove reserved ZP's from existing platform + program.getReservedZps().removeAll(program.getTargetPlatform().getReservedZps()); + // Set the new program platform program.setTargetPlatform(targetPlatform); // Define macros from new platform! if(program.getTargetPlatform().getDefines() != null) for(String macroName : program.getTargetPlatform().getDefines().keySet()) define(macroName, program.getTargetPlatform().getDefines().get(macroName)); + // Add reserved ZP's from new platform + program.addReservedZps(program.getTargetPlatform().getReservedZps()); // Re-initialize ASM fragment synthesizer program.initAsmFragmentSynthesizer(); } else { diff --git a/src/main/java/dk/camelot64/kickc/parser/CTargetPlatformParser.java b/src/main/java/dk/camelot64/kickc/parser/CTargetPlatformParser.java index 3306b0276..9e5a11436 100644 --- a/src/main/java/dk/camelot64/kickc/parser/CTargetPlatformParser.java +++ b/src/main/java/dk/camelot64/kickc/parser/CTargetPlatformParser.java @@ -1,20 +1,19 @@ package dk.camelot64.kickc.parser; +import dk.camelot64.kickc.NumberParser; import dk.camelot64.kickc.SourceLoader; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.TargetCpu; import dk.camelot64.kickc.model.TargetPlatform; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonReader; -import javax.json.JsonValue; +import javax.json.*; import javax.json.stream.JsonParsingException; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Path; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; @@ -54,6 +53,39 @@ public class CTargetPlatformParser { if(outExtension != null) targetPlatform.setOutFileExtension(outExtension); } + { + final JsonArray zpReserves = platformJson.getJsonArray("zp_reserve"); + if(zpReserves != null) { + List reservedZps = new ArrayList<>(); + for(JsonValue zpReserve : zpReserves) { + if(zpReserve instanceof JsonString) { + final String zpReserveStr = ((JsonString) zpReserve).getString(); + if(!zpReserveStr.contains("..")) { + // A single zeropage address + final Number zpReserveNumber = NumberParser.parseLiteral(zpReserveStr); + reservedZps.add(zpReserveNumber.intValue()); + } else { + // A range of zeropage addresses + final int split = zpReserveStr.indexOf(".."); + final String startStr = zpReserveStr.substring(0, split); + final String endStr = zpReserveStr.substring(split+2); + final Number startZp = NumberParser.parseLiteral(startStr); + final Number endZp = NumberParser.parseLiteral(endStr); + int zp = startZp.intValue(); + while(zp<=endZp.intValue()) { + reservedZps.add(zp); + zp++; + } + } + } else if(zpReserve instanceof JsonNumber) { + reservedZps.add(((JsonNumber) zpReserve).intValue()); + } else { + throw new CompileError("Cannot handle zp_reserve value " + zpReserve.toString()); + } + } + targetPlatform.setReservedZps(reservedZps); + } + } { final JsonObject defines = platformJson.getJsonObject("defines"); if(defines != null) { diff --git a/src/main/kc/target/atari2600.ld b/src/main/kc/target/atari2600.ld index eb3bada35..b5eef6949 100644 --- a/src/main/kc/target/atari2600.ld +++ b/src/main/kc/target/atari2600.ld @@ -3,7 +3,6 @@ .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors .word %E // NMI .word %E // RESET diff --git a/src/main/kc/target/atari2600.tgt b/src/main/kc/target/atari2600.tgt index 33a0d738d..1dff185b3 100644 --- a/src/main/kc/target/atari2600.tgt +++ b/src/main/kc/target/atari2600.tgt @@ -3,6 +3,7 @@ "link": "atari2600.ld", "cpu": "MOS6502X", "emulator": "stella", + "zp_reserve": [ "0x00..0x7f" ], "defines": { "__ATARI2600__": 1 } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index cfc9d033a..99ad2ae53 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -4382,6 +4382,7 @@ public class TestPrograms { final TargetPlatform targetPlatform = CTargetPlatformParser.parseTargetPlatformFile(TargetPlatform.DEFAULT_NAME, platformFile, filePath, program.getTargetPlatformPaths()); program.setTargetPlatform(targetPlatform); compiler.initAsmFragmentSynthesizer(asmFragmentSynthesizer); + program.addReservedZps(program.getTargetPlatform().getReservedZps()); compiler.compile(files, program.getTargetPlatform().getDefines()); compileAsm(fileName, program); boolean success = true; diff --git a/src/test/kc/examples/atari2600/atari2600-demo.c b/src/test/kc/examples/atari2600/atari2600-demo.c index 181854cff..d14a93b1e 100644 --- a/src/test/kc/examples/atari2600/atari2600-demo.c +++ b/src/test/kc/examples/atari2600/atari2600-demo.c @@ -3,16 +3,14 @@ #pragma target(atari2600) #include -// Variables -#pragma data_seg(Vars) -char __mem idx=0; - -// Data -#pragma data_seg(Data) +// Sinus table const char SINTABLE[0x100] = kickasm {{ .fill $100, round(127.5+127.5*sin(2*PI*i/256)) }}; +// Counts frames +char idx=0; + void main() { TIA->PF0 = 0b10100000; diff --git a/src/test/kc/examples/atari2600/atari2600-sprites.c b/src/test/kc/examples/atari2600/atari2600-sprites.c index 7dd6a3e7a..4925cc0aa 100644 --- a/src/test/kc/examples/atari2600/atari2600-sprites.c +++ b/src/test/kc/examples/atari2600/atari2600-sprites.c @@ -2,14 +2,13 @@ // Source: https://atariage.com/forums/blogs/entry/11109-step-1-generate-a-stable-display/ #pragma target(atari2600) #include -#pragma var_model(mem) -// Data -#pragma data_seg(Data) +// Sinus table const char SINTABLE_160[0x100] = kickasm {{ .fill $100, 10+round(64.5+64.5*sin(2*PI*i/256)) }}; +// The letter C char SPRITE_C[] = { 0, 0b00011000, @@ -47,8 +46,6 @@ char SPRITE_C[] = { 0 }; -// Variables -#pragma data_seg(Vars) // Counts frames char idx; char idx2 = 57; diff --git a/src/test/ref/examples/atari2600/atari2600-demo.asm b/src/test/ref/examples/atari2600/atari2600-demo.asm index b611d0b8b..d24789eb1 100644 --- a/src/test/ref/examples/atari2600/atari2600-demo.asm +++ b/src/test/ref/examples/atari2600/atari2600-demo.asm @@ -5,7 +5,6 @@ .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors .word main // NMI .word main // RESET @@ -26,6 +25,8 @@ .label TIA = 0 // Atari RIOT registers .label RIOT = $280 + // Counts frames + .label idx = $80 .segment Code main: { // TIA->PF0 = 0b10100000 @@ -41,7 +42,7 @@ main: { lda #$55 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF lda #0 - sta idx + sta.z idx __b2: // TIA->VSYNC = 2 // Vertical Sync @@ -78,9 +79,9 @@ main: { sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK // c = SINTABLE[idx++] // D1=1, turns off Vertical Blank signal (image output on) - ldy idx + ldy.z idx ldx SINTABLE,y - inc idx + inc.z idx tay __b6: // for(char i=0;i<192;i++) @@ -141,8 +142,7 @@ main: { jmp __b3 } .segment Data +// Sinus table SINTABLE: .fill $100, round(127.5+127.5*sin(2*PI*i/256)) -.segment Vars - idx: .byte 0 diff --git a/src/test/ref/examples/atari2600/atari2600-demo.log b/src/test/ref/examples/atari2600/atari2600-demo.log index 84ec031d5..5be5366b4 100644 --- a/src/test/ref/examples/atari2600/atari2600-demo.log +++ b/src/test/ref/examples/atari2600/atari2600-demo.log @@ -532,9 +532,9 @@ Complete equivalence classes [ idx#12 idx#1 ] [ main::i#2 main::i#1 ] [ main::c#2 main::c#0 main::c#1 ] -Allocated mem[1] [ idx#12 idx#1 ] -Allocated zp[1]:2 [ main::i#2 main::i#1 ] -Allocated zp[1]:3 [ main::c#2 main::c#0 main::c#1 ] +Allocated zp[1]:128 [ idx#12 idx#1 ] +Allocated zp[1]:129 [ main::i#2 main::i#1 ] +Allocated zp[1]:130 [ main::c#2 main::c#0 main::c#1 ] INITIAL ASM Target platform is atari2600 / MOS6502X @@ -547,7 +547,6 @@ Target platform is atari2600 / MOS6502X .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors .word main // NMI .word main // RESET @@ -569,6 +568,8 @@ Target platform is atari2600 / MOS6502X .label TIA = 0 // Atari RIOT registers .label RIOT = $280 + // Counts frames + .label idx = $80 // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] @@ -586,8 +587,8 @@ __bend: .segment Code // main main: { - .label c = 3 - .label i = 2 + .label c = $82 + .label i = $81 // [4] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF0) ← (byte) $a0 -- _deref_pbuc1=vbuc2 lda #$a0 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_PF0 @@ -602,9 +603,9 @@ main: { sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF // [8] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: - // [8] phi (byte) idx#12 = (byte) 0 [phi:main->main::@1#0] -- vbum1=vbuc1 + // [8] phi (byte) idx#12 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #0 - sta idx + sta.z idx jmp __b1 // main::@1 __b1: @@ -655,13 +656,13 @@ main: { // For now we're just going to output 192 colored scanlines lines so we have something to see. lda #0 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK - // [17] (byte) main::c#0 ← *((const to_nomodify byte*) SINTABLE + (byte) idx#12) -- vbuz1=pbuc1_derefidx_vbum2 + // [17] (byte) main::c#0 ← *((const to_nomodify byte*) SINTABLE + (byte) idx#12) -- vbuz1=pbuc1_derefidx_vbuz2 // D1=1, turns off Vertical Blank signal (image output on) - ldy idx + ldy.z idx lda SINTABLE,y sta.z c - // [18] (byte) idx#1 ← ++ (byte) idx#12 -- vbum1=_inc_vbum1 - inc idx + // [18] (byte) idx#1 ← ++ (byte) idx#12 -- vbuz1=_inc_vbuz1 + inc.z idx // [19] phi from main::@5 to main::@6 [phi:main::@5->main::@6] __b6_from___b5: // [19] phi (byte) main::c#2 = (byte) main::c#0 [phi:main::@5->main::@6#0] -- register_copy @@ -752,11 +753,10 @@ main: { } // File Data .segment Data +// Sinus table SINTABLE: .fill $100, round(127.5+127.5*sin(2*PI*i/256)) -.segment Vars - idx: .byte 0 REGISTER UPLIFT POTENTIAL REGISTERS Statement [4] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF0) ← (byte) $a0 [ ] ( main:2 [ ] { } ) always clobbers reg byte a @@ -764,7 +764,7 @@ Statement [5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) Statement [6] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF2) ← (byte) $aa [ ] ( main:2 [ ] { } ) always clobbers reg byte a Statement [7] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF) ← (byte) $55 [ ] ( main:2 [ ] { } ) always clobbers reg byte a Statement [9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2 [ idx#12 ] ( main:2 [ idx#12 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for mem[1] [ idx#12 idx#1 ] +Removing always clobbered register reg byte a as potential for zp[1]:128 [ idx#12 idx#1 ] Statement [10] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte)(number) $29*(number) $4c/(number) $40 [ idx#12 ] ( main:2 [ idx#12 ] { } ) always clobbers reg byte a Statement [11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#12 ] ( main:2 [ idx#12 ] { } ) always clobbers reg byte a Statement [12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#12 ] ( main:2 [ idx#12 ] { } ) always clobbers reg byte a @@ -779,8 +779,8 @@ Statement [24] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) Statement [25] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@10 [ idx#1 ] ( main:2 [ idx#1 ] { } ) always clobbers reg byte a Statement [26] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 ] ( main:2 [ idx#1 ] { } ) always clobbers reg byte a Statement [27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 main::i#2 main::c#2 ] ( main:2 [ idx#1 main::i#2 main::c#2 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] -Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::c#2 main::c#0 main::c#1 ] +Removing always clobbered register reg byte a as potential for zp[1]:129 [ main::i#2 main::i#1 ] +Removing always clobbered register reg byte a as potential for zp[1]:130 [ main::c#2 main::c#0 main::c#1 ] Statement [35] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#12 ] ( main:2 [ idx#12 ] { } ) always clobbers reg byte a Statement [4] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF0) ← (byte) $a0 [ ] ( main:2 [ ] { } ) always clobbers reg byte a Statement [5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_PF1) ← (byte) $55 [ ] ( main:2 [ ] { } ) always clobbers reg byte a @@ -802,24 +802,24 @@ Statement [25] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+ Statement [26] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 ] ( main:2 [ idx#1 ] { } ) always clobbers reg byte a Statement [27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 main::i#2 main::c#2 ] ( main:2 [ idx#1 main::i#2 main::c#2 ] { } ) always clobbers reg byte a Statement [35] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#12 ] ( main:2 [ idx#12 ] { } ) always clobbers reg byte a -Potential registers mem[1] [ idx#12 idx#1 ] : mem[1] , reg byte x , reg byte y , -Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y , -Potential registers zp[1]:3 [ main::c#2 main::c#0 main::c#1 ] : zp[1]:3 , reg byte x , reg byte y , +Potential registers zp[1]:128 [ idx#12 idx#1 ] : zp[1]:128 , reg byte x , reg byte y , +Potential registers zp[1]:129 [ main::i#2 main::i#1 ] : zp[1]:129 , reg byte x , reg byte y , +Potential registers zp[1]:130 [ main::c#2 main::c#0 main::c#1 ] : zp[1]:130 , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [main] 2,335.67: zp[1]:2 [ main::i#2 main::i#1 ] 1,990.5: zp[1]:3 [ main::c#2 main::c#0 main::c#1 ] -Uplift Scope [] 174.19: mem[1] [ idx#12 idx#1 ] +Uplift Scope [main] 2,335.67: zp[1]:129 [ main::i#2 main::i#1 ] 1,990.5: zp[1]:130 [ main::c#2 main::c#0 main::c#1 ] +Uplift Scope [] 174.19: zp[1]:128 [ idx#12 idx#1 ] Uplift Scope [ATARI_TIA_WRITE] Uplift Scope [ATARI_TIA_READ] Uplift Scope [MOS6532_RIOT] -Uplifting [main] best 9401 combination reg byte y [ main::i#2 main::i#1 ] reg byte x [ main::c#2 main::c#0 main::c#1 ] -Uplifting [] best 9401 combination mem[1] [ idx#12 idx#1 ] -Uplifting [ATARI_TIA_WRITE] best 9401 combination -Uplifting [ATARI_TIA_READ] best 9401 combination -Uplifting [MOS6532_RIOT] best 9401 combination -Attempting to uplift remaining variables inmem[1] [ idx#12 idx#1 ] -Uplifting [] best 9401 combination mem[1] [ idx#12 idx#1 ] +Uplifting [main] best 9371 combination reg byte y [ main::i#2 main::i#1 ] reg byte x [ main::c#2 main::c#0 main::c#1 ] +Uplifting [] best 9371 combination zp[1]:128 [ idx#12 idx#1 ] +Uplifting [ATARI_TIA_WRITE] best 9371 combination +Uplifting [ATARI_TIA_READ] best 9371 combination +Uplifting [MOS6532_RIOT] best 9371 combination +Attempting to uplift remaining variables inzp[1]:128 [ idx#12 idx#1 ] +Uplifting [] best 9371 combination zp[1]:128 [ idx#12 idx#1 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -831,7 +831,6 @@ ASSEMBLER BEFORE OPTIMIZATION .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors .word main // NMI .word main // RESET @@ -853,6 +852,8 @@ ASSEMBLER BEFORE OPTIMIZATION .label TIA = 0 // Atari RIOT registers .label RIOT = $280 + // Counts frames + .label idx = $80 // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] @@ -884,9 +885,9 @@ main: { sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF // [8] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: - // [8] phi (byte) idx#12 = (byte) 0 [phi:main->main::@1#0] -- vbum1=vbuc1 + // [8] phi (byte) idx#12 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #0 - sta idx + sta.z idx jmp __b1 // main::@1 __b1: @@ -937,12 +938,12 @@ main: { // For now we're just going to output 192 colored scanlines lines so we have something to see. lda #0 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK - // [17] (byte) main::c#0 ← *((const to_nomodify byte*) SINTABLE + (byte) idx#12) -- vbuxx=pbuc1_derefidx_vbum1 + // [17] (byte) main::c#0 ← *((const to_nomodify byte*) SINTABLE + (byte) idx#12) -- vbuxx=pbuc1_derefidx_vbuz1 // D1=1, turns off Vertical Blank signal (image output on) - ldy idx + ldy.z idx ldx SINTABLE,y - // [18] (byte) idx#1 ← ++ (byte) idx#12 -- vbum1=_inc_vbum1 - inc idx + // [18] (byte) idx#1 ← ++ (byte) idx#12 -- vbuz1=_inc_vbuz1 + inc.z idx // [19] phi from main::@5 to main::@6 [phi:main::@5->main::@6] __b6_from___b5: // [19] phi (byte) main::c#2 = (byte) main::c#0 [phi:main::@5->main::@6#0] -- register_copy @@ -1026,11 +1027,10 @@ main: { } // File Data .segment Data +// Sinus table SINTABLE: .fill $100, round(127.5+127.5*sin(2*PI*i/256)) -.segment Vars - idx: .byte 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __b1 @@ -1156,8 +1156,8 @@ FINAL SYMBOL TABLE }} (const nomodify struct ATARI_TIA_WRITE*) TIA = (struct ATARI_TIA_WRITE*) 0 (byte) idx -(byte) idx#1 idx mem[1] 64.82352941176471 -(byte) idx#12 idx mem[1] 109.36363636363637 +(byte) idx#1 idx zp[1]:128 64.82352941176471 +(byte) idx#12 idx zp[1]:128 109.36363636363637 (void()) main() (label) main::@1 (label) main::@10 @@ -1177,13 +1177,13 @@ FINAL SYMBOL TABLE (byte) main::i#1 reg byte y 2002.0 (byte) main::i#2 reg byte y 333.6666666666667 -mem[1] [ idx#12 idx#1 ] +zp[1]:128 [ idx#12 idx#1 ] reg byte y [ main::i#2 main::i#1 ] reg byte x [ main::c#2 main::c#0 main::c#1 ] FINAL ASSEMBLER -Score: 8289 +Score: 8259 // File Comments // Minimal Atari 2600 VCS Program @@ -1194,7 +1194,6 @@ Score: 8289 .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors .word main // NMI .word main // RESET @@ -1216,6 +1215,8 @@ Score: 8289 .label TIA = 0 // Atari RIOT registers .label RIOT = $280 + // Counts frames + .label idx = $80 // @begin // [1] phi from @begin to @1 [phi:@begin->@1] // @1 @@ -1242,9 +1243,9 @@ main: { lda #$55 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUPF // [8] phi from main to main::@1 [phi:main->main::@1] - // [8] phi (byte) idx#12 = (byte) 0 [phi:main->main::@1#0] -- vbum1=vbuc1 + // [8] phi (byte) idx#12 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #0 - sta idx + sta.z idx // main::@1 // main::@2 __b2: @@ -1292,12 +1293,12 @@ main: { // For now we're just going to output 192 colored scanlines lines so we have something to see. sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK // c = SINTABLE[idx++] - // [17] (byte) main::c#0 ← *((const to_nomodify byte*) SINTABLE + (byte) idx#12) -- vbuxx=pbuc1_derefidx_vbum1 + // [17] (byte) main::c#0 ← *((const to_nomodify byte*) SINTABLE + (byte) idx#12) -- vbuxx=pbuc1_derefidx_vbuz1 // D1=1, turns off Vertical Blank signal (image output on) - ldy idx + ldy.z idx ldx SINTABLE,y - // [18] (byte) idx#1 ← ++ (byte) idx#12 -- vbum1=_inc_vbum1 - inc idx + // [18] (byte) idx#1 ← ++ (byte) idx#12 -- vbuz1=_inc_vbuz1 + inc.z idx // [19] phi from main::@5 to main::@6 [phi:main::@5->main::@6] // [19] phi (byte) main::c#2 = (byte) main::c#0 [phi:main::@5->main::@6#0] -- register_copy // [19] phi (byte) main::i#2 = (byte) 0 [phi:main::@5->main::@6#1] -- vbuyy=vbuc1 @@ -1389,9 +1390,8 @@ main: { } // File Data .segment Data +// Sinus table SINTABLE: .fill $100, round(127.5+127.5*sin(2*PI*i/256)) -.segment Vars - idx: .byte 0 diff --git a/src/test/ref/examples/atari2600/atari2600-demo.sym b/src/test/ref/examples/atari2600/atari2600-demo.sym index 1097bdef9..8f934f6f2 100644 --- a/src/test/ref/examples/atari2600/atari2600-demo.sym +++ b/src/test/ref/examples/atari2600/atari2600-demo.sym @@ -85,8 +85,8 @@ }} (const nomodify struct ATARI_TIA_WRITE*) TIA = (struct ATARI_TIA_WRITE*) 0 (byte) idx -(byte) idx#1 idx mem[1] 64.82352941176471 -(byte) idx#12 idx mem[1] 109.36363636363637 +(byte) idx#1 idx zp[1]:128 64.82352941176471 +(byte) idx#12 idx zp[1]:128 109.36363636363637 (void()) main() (label) main::@1 (label) main::@10 @@ -106,6 +106,6 @@ (byte) main::i#1 reg byte y 2002.0 (byte) main::i#2 reg byte y 333.6666666666667 -mem[1] [ idx#12 idx#1 ] +zp[1]:128 [ idx#12 idx#1 ] reg byte y [ main::i#2 main::i#1 ] reg byte x [ main::c#2 main::c#0 main::c#1 ] diff --git a/src/test/ref/examples/atari2600/atari2600-sprites.asm b/src/test/ref/examples/atari2600/atari2600-sprites.asm index 811f8c588..95a95481e 100644 --- a/src/test/ref/examples/atari2600/atari2600-sprites.asm +++ b/src/test/ref/examples/atari2600/atari2600-sprites.asm @@ -5,11 +5,10 @@ .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors -.word main // NMI -.word main // RESET -.word main // IRQ +.word __bbegin // NMI +.word __bbegin // RESET +.word __bbegin // IRQ .segment Code // The number of CPU cycles per scanline @@ -33,6 +32,19 @@ .label TIA = 0 // Atari RIOT registers .label RIOT = $280 + .label p0_xpos = $82 + // Counts frames + .label idx = $80 + // Player 0 Y position + .label p0_ypos = $83 + .label idx2 = $81 +__bbegin: + // p0_xpos + // Player 0 X position + lda #0 + sta.z p0_xpos + jsr main + rts .segment Code main: { // asm @@ -51,9 +63,9 @@ main: { lda #5 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0 lda #$39 - sta idx2 + sta.z idx2 lda #0 - sta idx + sta.z idx __b2: // TIA->VSYNC = 2 // Vertical Sync @@ -93,17 +105,17 @@ main: { sta TIA_HMP0 sta TIA_RESP0 // p0_xpos = SINTABLE_160[idx++] - ldy idx + ldy.z idx lda SINTABLE_160,y - sta p0_xpos + sta.z p0_xpos // p0_xpos = SINTABLE_160[idx++]; - inc idx + inc.z idx // p0_ypos = SINTABLE_160[idx2++] - ldy idx2 + ldy.z idx2 lda SINTABLE_160,y - sta p0_ypos + sta.z p0_ypos // p0_ypos = SINTABLE_160[idx2++]; - inc idx2 + inc.z idx2 // TIA->WSYNC = 0 // Execute horisontal movement lda #0 @@ -168,7 +180,7 @@ main: { cpy #0 bne __b9 // if(p0_ypos==i) - cpx p0_ypos + cpx.z p0_ypos bne __b10 ldy #1 jmp __b10 @@ -197,15 +209,9 @@ main: { jmp __b3 } .segment Data + // Sinus table SINTABLE_160: .fill $100, 10+round(64.5+64.5*sin(2*PI*i/256)) + // The letter C SPRITE_C: .byte 0, $18, $18, $18, $18, $3c, $3c, $3c, $3c, $66, $66, $66, $66, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $66, $66, $66, $66, $3c, $3c, $3c, $3c, $18, $18, $18, $18, 0 -.segment Vars - // Player 0 X position - p0_xpos: .byte 0 - // Counts frames - idx: .byte 0 - // Player 0 Y position - p0_ypos: .byte 0 - idx2: .byte 0 diff --git a/src/test/ref/examples/atari2600/atari2600-sprites.cfg b/src/test/ref/examples/atari2600/atari2600-sprites.cfg index ff483ace3..74cef8410 100644 --- a/src/test/ref/examples/atari2600/atari2600-sprites.cfg +++ b/src/test/ref/examples/atari2600/atari2600-sprites.cfg @@ -1,5 +1,5 @@ @begin: scope:[] from - [0] phi() + [0] (byte) p0_xpos ← (byte) 0 to:@1 @1: scope:[] from @begin [1] phi() diff --git a/src/test/ref/examples/atari2600/atari2600-sprites.log b/src/test/ref/examples/atari2600/atari2600-sprites.log index 00e23c605..e8022a452 100644 --- a/src/test/ref/examples/atari2600/atari2600-sprites.log +++ b/src/test/ref/examples/atari2600/atari2600-sprites.log @@ -6,6 +6,7 @@ CONTROL FLOW GRAPH SSA @begin: scope:[] from (byte) idx#0 ← (byte) 0 (byte) idx2#0 ← (byte) $39 + (byte) p0_xpos ← (byte) 0 (byte) p0_ypos#0 ← (byte) 0 to:@1 @@ -376,7 +377,7 @@ SYMBOL TABLE SSA (byte) main::p0_idx#7 (byte) main::p0_idx#8 (byte) main::p0_idx#9 -(byte) p0_xpos loadstore = (byte) 0 +(byte) p0_xpos loadstore (byte) p0_ypos (byte) p0_ypos#0 (byte) p0_ypos#1 @@ -525,7 +526,7 @@ Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0 Successful SSA optimization PassNFinalizeNumberTypeConversions -Inversing boolean not [55] (bool~) main::$2 ← (byte) p0_ypos#4 != (byte) main::i#4 from [54] (bool~) main::$1 ← (byte) p0_ypos#4 == (byte) main::i#4 +Inversing boolean not [56] (bool~) main::$2 ← (byte) p0_ypos#4 != (byte) main::i#4 from [55] (bool~) main::$1 ← (byte) p0_ypos#4 == (byte) main::i#4 Successful SSA optimization Pass2UnaryNotSimplification Alias idx#2 = idx#4 idx#7 idx#5 Alias idx2#2 = idx2#4 idx2#7 idx2#5 @@ -569,13 +570,13 @@ Identical Phi Values (byte) idx#3 (byte) idx#2 Identical Phi Values (byte) p0_ypos#3 (byte) p0_ypos#2 Identical Phi Values (byte) idx2#3 (byte) idx2#2 Successful SSA optimization Pass2IdenticalPhiElimination -Simple Condition (bool~) main::$4 [10] if((number) 0!=(number) 1) goto main::@2 -Simple Condition (bool~) main::$5 [26] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4 -Simple Condition (bool~) main::$0 [34] if((byte) main::i#2<(byte) $c0) goto main::@7 -Simple Condition (bool~) main::$6 [38] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9 -Simple Condition (bool~) main::$3 [46] if((byte) main::gfx#0==(byte) 0) goto main::@11 -Simple Condition (bool~) main::$2 [48] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@10 -Simple Condition (bool~) main::$7 [56] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@16 +Simple Condition (bool~) main::$4 [11] if((number) 0!=(number) 1) goto main::@2 +Simple Condition (bool~) main::$5 [27] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4 +Simple Condition (bool~) main::$0 [35] if((byte) main::i#2<(byte) $c0) goto main::@7 +Simple Condition (bool~) main::$6 [39] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9 +Simple Condition (bool~) main::$3 [47] if((byte) main::gfx#0==(byte) 0) goto main::@11 +Simple Condition (bool~) main::$2 [49] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@10 +Simple Condition (bool~) main::$7 [57] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@16 Successful SSA optimization Pass2ConditionalJumpSimplification Constant (const byte) idx#0 = 0 Constant (const byte) idx2#0 = $39 @@ -585,10 +586,10 @@ Constant (const byte) main::i#0 = 1 Constant (const byte) main::p0_idx#1 = 1 Constant (const byte) main::p0_idx#2 = 0 Successful SSA optimization Pass2ConstantIdentification -if() condition always true - replacing block destination [10] if((number) 0!=(number) 1) goto main::@2 +if() condition always true - replacing block destination [11] if((number) 0!=(number) 1) goto main::@2 Successful SSA optimization Pass2ConstantIfs -Simplifying expression containing zero (byte*)TIA in [11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VSYNC) ← (byte) 2 -Simplifying expression containing zero (byte*)TIA in [16] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VSYNC) ← (byte) 0 +Simplifying expression containing zero (byte*)TIA in [12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VSYNC) ← (byte) 2 +Simplifying expression containing zero (byte*)TIA in [17] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VSYNC) ← (byte) 0 Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused variable - keeping the phi block (byte) p0_ypos#2 Eliminating unused constant (const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VSYNC @@ -612,7 +613,6 @@ Constant inlined idx#0 = (byte) 0 Successful SSA optimization Pass2ConstantInlining Added new block during phi lifting main::@17(between main::@15 and main::@1) Added new block during phi lifting main::@18(between main::@12 and main::@10) -Adding NOP phi() at start of @begin Adding NOP phi() at start of @1 Adding NOP phi() at start of @2 Adding NOP phi() at start of @end @@ -638,14 +638,13 @@ Renumbering block main::@14 to main::@12 Renumbering block main::@15 to main::@13 Renumbering block main::@16 to main::@14 Renumbering block main::@18 to main::@15 -Adding NOP phi() at start of @begin Adding NOP phi() at start of @1 Adding NOP phi() at start of @end Adding NOP phi() at start of main::@15 FINAL CONTROL FLOW GRAPH @begin: scope:[] from - [0] phi() + [0] (byte) p0_xpos ← (byte) 0 to:@1 @1: scope:[] from @begin [1] phi() @@ -817,7 +816,7 @@ VARIABLE REGISTER WEIGHTS (byte) main::p0_idx#3 2002.0 (byte) main::p0_idx#4 500.5 (byte) main::p0_idx#8 1501.5 -(byte) p0_xpos loadstore 2.4047619047619047 = (byte) 0 +(byte) p0_xpos loadstore 2.452380952380952 (byte) p0_ypos (byte) p0_ypos#1 52.476190476190474 @@ -837,13 +836,13 @@ Complete equivalence classes [ p0_xpos ] [ p0_ypos#1 ] [ main::gfx#0 ] -Allocated mem[1] [ idx#2 idx#1 ] -Allocated mem[1] [ idx2#2 idx2#1 ] -Allocated mem[1] [ main::i#2 main::i#1 ] -Allocated mem[1] [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] -Allocated mem[1] [ p0_xpos ] -Allocated mem[1] [ p0_ypos#1 ] -Allocated mem[1] [ main::gfx#0 ] +Allocated zp[1]:128 [ idx#2 idx#1 ] +Allocated zp[1]:129 [ idx2#2 idx2#1 ] +Allocated zp[1]:130 [ main::i#2 main::i#1 ] +Allocated zp[1]:131 [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] +Allocated zp[1]:132 [ p0_xpos ] +Allocated zp[1]:133 [ p0_ypos#1 ] +Allocated zp[1]:134 [ main::gfx#0 ] INITIAL ASM Target platform is atari2600 / MOS6502X @@ -856,11 +855,10 @@ Target platform is atari2600 / MOS6502X .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors -.word main // NMI -.word main // RESET -.word main // IRQ +.word __bbegin // NMI +.word __bbegin // RESET +.word __bbegin // IRQ .segment Code // Global Constants & labels @@ -885,8 +883,18 @@ Target platform is atari2600 / MOS6502X .label TIA = 0 // Atari RIOT registers .label RIOT = $280 + .label p0_xpos = $84 + // Counts frames + .label idx = $80 + // Player 0 Y position + .label p0_ypos = $85 + .label idx2 = $81 // @begin __bbegin: + // [0] (byte) p0_xpos ← (byte) 0 -- vbuz1=vbuc1 + // Player 0 X position + lda #0 + sta.z p0_xpos // [1] phi from @begin to @1 [phi:@begin->@1] __b1_from___bbegin: jmp __b1 @@ -902,6 +910,11 @@ __bend: .segment Code // main main: { + .label gfx = $86 + .label i = $82 + // index into p0 (0 when not active) + // Player 0 becomes active + .label p0_idx = $83 // asm { cld } cld // [5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0) ← (byte) $f0 -- _deref_pbuc1=vbuc2 @@ -919,12 +932,12 @@ main: { sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0 // [8] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: - // [8] phi (byte) idx2#2 = (byte) $39 [phi:main->main::@1#0] -- vbum1=vbuc1 + // [8] phi (byte) idx2#2 = (byte) $39 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #$39 - sta idx2 - // [8] phi (byte) idx#2 = (byte) 0 [phi:main->main::@1#1] -- vbum1=vbuc1 + sta.z idx2 + // [8] phi (byte) idx#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1 lda #0 - sta idx + sta.z idx jmp __b1 // main::@1 __b1: @@ -973,18 +986,18 @@ main: { asl sta TIA_HMP0 sta TIA_RESP0 - // [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) -- vbum1=pbuc1_derefidx_vbum2 - ldy idx + // [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) -- vbuz1=pbuc1_derefidx_vbuz2 + ldy.z idx lda SINTABLE_160,y - sta p0_xpos - // [17] (byte) idx#1 ← ++ (byte) idx#2 -- vbum1=_inc_vbum1 - inc idx - // [18] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2) -- vbum1=pbuc1_derefidx_vbum2 - ldy idx2 + sta.z p0_xpos + // [17] (byte) idx#1 ← ++ (byte) idx#2 -- vbuz1=_inc_vbuz1 + inc.z idx + // [18] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2) -- vbuz1=pbuc1_derefidx_vbuz2 + ldy.z idx2 lda SINTABLE_160,y - sta p0_ypos - // [19] (byte) idx2#1 ← ++ (byte) idx2#2 -- vbum1=_inc_vbum1 - inc idx2 + sta.z p0_ypos + // [19] (byte) idx2#1 ← ++ (byte) idx2#2 -- vbuz1=_inc_vbuz1 + inc.z idx2 // [20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 -- _deref_pbuc1=vbuc2 // Execute horisontal movement lda #0 @@ -1015,17 +1028,17 @@ main: { sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK // [25] phi from main::@5 to main::@6 [phi:main::@5->main::@6] __b6_from___b5: - // [25] phi (byte) main::p0_idx#4 = (byte) 0 [phi:main::@5->main::@6#0] -- vbum1=vbuc1 + // [25] phi (byte) main::p0_idx#4 = (byte) 0 [phi:main::@5->main::@6#0] -- vbuz1=vbuc1 lda #0 - sta p0_idx - // [25] phi (byte) main::i#2 = (byte) 1 [phi:main::@5->main::@6#1] -- vbum1=vbuc1 + sta.z p0_idx + // [25] phi (byte) main::i#2 = (byte) 1 [phi:main::@5->main::@6#1] -- vbuz1=vbuc1 lda #1 - sta i + sta.z i jmp __b6 // main::@6 __b6: - // [26] if((byte) main::i#2<(byte) $c0) goto main::@7 -- vbum1_lt_vbuc1_then_la1 - lda i + // [26] if((byte) main::i#2<(byte) $c0) goto main::@7 -- vbuz1_lt_vbuc1_then_la1 + lda.z i cmp #$c0 bcc __b7 jmp __b8 @@ -1072,25 +1085,25 @@ main: { // Wait for SYNC (halts CPU until end of scanline) lda #0 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC - // [34] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) main::i#2 -- _deref_pbuc1=vbum1 - lda i + // [34] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) main::i#2 -- _deref_pbuc1=vbuz1 + lda.z i sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK - // [35] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9 -- vbuc1_neq_vbum1_then_la1 + // [35] if((byte) 0!=(byte) main::p0_idx#4) goto main::@9 -- vbuc1_neq_vbuz1_then_la1 lda #0 - cmp p0_idx + cmp.z p0_idx bne __b9 jmp __b11 // main::@11 __b11: - // [36] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15 -- vbum1_neq_vbum2_then_la1 - lda p0_ypos - cmp i + // [36] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15 -- vbuz1_neq_vbuz2_then_la1 + lda.z p0_ypos + cmp.z i bne __b15_from___b11 // [38] phi from main::@11 to main::@10 [phi:main::@11->main::@10] __b10_from___b11: - // [38] phi (byte) main::p0_idx#8 = (byte) 1 [phi:main::@11->main::@10#0] -- vbum1=vbuc1 + // [38] phi (byte) main::p0_idx#8 = (byte) 1 [phi:main::@11->main::@10#0] -- vbuz1=vbuc1 lda #1 - sta p0_idx + sta.z p0_idx jmp __b10 // [37] phi from main::@11 to main::@15 [phi:main::@11->main::@15] __b15_from___b11: @@ -1104,14 +1117,14 @@ main: { jmp __b10 // [38] phi from main::@9 to main::@10 [phi:main::@9->main::@10] __b10_from___b9: - // [38] phi (byte) main::p0_idx#8 = (byte) 0 [phi:main::@9->main::@10#0] -- vbum1=vbuc1 + // [38] phi (byte) main::p0_idx#8 = (byte) 0 [phi:main::@9->main::@10#0] -- vbuz1=vbuc1 lda #0 - sta p0_idx + sta.z p0_idx jmp __b10 // main::@10 __b10: - // [39] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbum1=_inc_vbum1 - inc i + // [39] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 + inc.z i // [25] phi from main::@10 to main::@6 [phi:main::@10->main::@6] __b6_from___b10: // [25] phi (byte) main::p0_idx#4 = (byte) main::p0_idx#8 [phi:main::@10->main::@6#0] -- register_copy @@ -1119,23 +1132,23 @@ main: { jmp __b6 // main::@9 __b9: - // [40] (byte) main::gfx#0 ← *((const byte*) SPRITE_C + (byte) main::p0_idx#4) -- vbum1=pbuc1_derefidx_vbum2 + // [40] (byte) main::gfx#0 ← *((const byte*) SPRITE_C + (byte) main::p0_idx#4) -- vbuz1=pbuc1_derefidx_vbuz2 // Player 0 is active - show it - ldy p0_idx + ldy.z p0_idx lda SPRITE_C,y - sta gfx - // [41] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) main::gfx#0 -- _deref_pbuc1=vbum1 - lda gfx + sta.z gfx + // [41] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) main::gfx#0 -- _deref_pbuc1=vbuz1 + lda.z gfx sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0 - // [42] if((byte) main::gfx#0==(byte) 0) goto main::@10 -- vbum1_eq_0_then_la1 - lda gfx + // [42] if((byte) main::gfx#0==(byte) 0) goto main::@10 -- vbuz1_eq_0_then_la1 + lda.z gfx cmp #0 beq __b10_from___b9 jmp __b12 // main::@12 __b12: - // [43] (byte) main::p0_idx#3 ← ++ (byte) main::p0_idx#4 -- vbum1=_inc_vbum1 - inc p0_idx + // [43] (byte) main::p0_idx#3 ← ++ (byte) main::p0_idx#4 -- vbuz1=_inc_vbuz1 + inc.z p0_idx jmp __b10_from___b12 // main::@4 __b4: @@ -1143,110 +1156,102 @@ main: { lda #0 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC jmp __b3 - .segment Vars - gfx: .byte 0 - i: .byte 0 - // index into p0 (0 when not active) - // Player 0 becomes active - p0_idx: .byte 0 } // File Data .segment Data + // Sinus table SINTABLE_160: .fill $100, 10+round(64.5+64.5*sin(2*PI*i/256)) + // The letter C SPRITE_C: .byte 0, $18, $18, $18, $18, $3c, $3c, $3c, $3c, $66, $66, $66, $66, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $66, $66, $66, $66, $3c, $3c, $3c, $3c, $18, $18, $18, $18, 0 -.segment Vars - // Player 0 X position - p0_xpos: .byte 0 - // Counts frames - idx: .byte 0 - // Player 0 Y position - p0_ypos: .byte 0 - idx2: .byte 0 REGISTER UPLIFT POTENTIAL REGISTERS +Statement [0] (byte) p0_xpos ← (byte) 0 [ p0_xpos ] ( [ p0_xpos ] { } ) always clobbers reg byte a Statement [5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0) ← (byte) $f0 [ p0_xpos ] ( main:2 [ p0_xpos ] { } ) always clobbers reg byte a Statement [6] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) $af [ p0_xpos ] ( main:2 [ p0_xpos ] { } ) always clobbers reg byte a Statement [7] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0) ← (byte) 5 [ p0_xpos ] ( main:2 [ p0_xpos ] { } ) always clobbers reg byte a -Statement [9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for mem[1] [ idx#2 idx#1 ] -Removing always clobbered register reg byte a as potential for mem[1] [ idx2#2 idx2#1 ] -Statement [10] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $29*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [14] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a +Statement [9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:128 [ idx#2 idx#1 ] +Removing always clobbered register reg byte a as potential for zp[1]:129 [ idx2#2 idx2#1 ] +Statement [10] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $29*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [14] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a Statement asm { ldap0_xpos staTIA_WSYNC sec !: sbc#$f bcs!- eor#7 asl asl asl asl staTIA_HMP0 staTIA_RESP0 } always clobbers reg byte a -Statement [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for mem[1] [ p0_ypos#1 ] -Statement [21] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [22] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [24] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [29] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [30] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $1b*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [31] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@14 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [32] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [33] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 main::i#2 main::p0_idx#4 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 main::i#2 main::p0_idx#4 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for mem[1] [ main::i#2 main::i#1 ] -Removing always clobbered register reg byte a as potential for mem[1] [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] -Statement [44] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:133 [ p0_ypos#1 ] +Statement [21] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [22] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [24] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [29] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [30] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $1b*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [31] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@14 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [32] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [33] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 main::i#2 main::p0_idx#4 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 main::i#2 main::p0_idx#4 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:130 [ main::i#2 main::i#1 ] +Removing always clobbered register reg byte a as potential for zp[1]:131 [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] +Statement [44] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [0] (byte) p0_xpos ← (byte) 0 [ p0_xpos ] ( [ p0_xpos ] { } ) always clobbers reg byte a Statement [5] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUP0) ← (byte) $f0 [ p0_xpos ] ( main:2 [ p0_xpos ] { } ) always clobbers reg byte a Statement [6] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_GRP0) ← (byte) $af [ p0_xpos ] ( main:2 [ p0_xpos ] { } ) always clobbers reg byte a Statement [7] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0) ← (byte) 5 [ p0_xpos ] ( main:2 [ p0_xpos ] { } ) always clobbers reg byte a -Statement [9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [10] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $29*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [14] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0 [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a +Statement [9] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 2 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [10] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $29*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [11] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [12] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [13] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [14] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA) ← (byte) 0 [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a Statement asm { ldap0_xpos staTIA_WSYNC sec !: sbc#$f bcs!- eor#7 asl asl asl asl staTIA_HMP0 staTIA_RESP0 } always clobbers reg byte a -Statement [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) [ idx#2 idx2#2 p0_xpos ] ( main:2 [ idx#2 idx2#2 p0_xpos ] { } ) always clobbers reg byte a -Statement [20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [21] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [22] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [24] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Statement [27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [29] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [30] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $1b*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [31] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@14 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [32] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos ] ( main:2 [ idx#1 idx2#1 p0_xpos ] { } ) always clobbers reg byte a -Statement [33] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 main::i#2 main::p0_idx#4 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 main::i#2 main::p0_idx#4 ] { } ) always clobbers reg byte a -Statement [44] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] ( main:2 [ idx#1 idx2#1 p0_xpos p0_ypos#1 ] { } ) always clobbers reg byte a -Potential registers mem[1] [ idx#2 idx#1 ] : mem[1] , reg byte x , reg byte y , -Potential registers mem[1] [ idx2#2 idx2#1 ] : mem[1] , reg byte x , reg byte y , -Potential registers mem[1] [ main::i#2 main::i#1 ] : mem[1] , reg byte x , reg byte y , -Potential registers mem[1] [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] : mem[1] , reg byte x , reg byte y , -Potential registers mem[1] [ p0_xpos ] : mem[1] , -Potential registers mem[1] [ p0_ypos#1 ] : mem[1] , reg byte x , reg byte y , -Potential registers mem[1] [ main::gfx#0 ] : mem[1] , reg byte a , reg byte x , reg byte y , +Statement [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) [ p0_xpos idx#2 idx2#2 ] ( main:2 [ p0_xpos idx#2 idx2#2 ] { } ) always clobbers reg byte a +Statement [20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [21] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_HMOVE) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [22] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@4 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [23] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [24] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Statement [27] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [28] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_VBLANK) ← (byte) 2 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [29] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_COLUBK) ← (byte) 0 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [30] *((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_TIM64T) ← (byte) $1b*(const nomodify byte) CYCLES_PER_SCANLINE/(byte) $40 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [31] if((byte) 0!=*((byte*)(const nomodify struct MOS6532_RIOT*) RIOT+(const byte) OFFSET_STRUCT_MOS6532_RIOT_INTIM)) goto main::@14 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [32] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 ] { } ) always clobbers reg byte a +Statement [33] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 main::i#2 main::p0_idx#4 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 main::i#2 main::p0_idx#4 ] { } ) always clobbers reg byte a +Statement [44] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] ( main:2 [ p0_xpos idx#1 idx2#1 p0_ypos#1 ] { } ) always clobbers reg byte a +Potential registers zp[1]:128 [ idx#2 idx#1 ] : zp[1]:128 , reg byte x , reg byte y , +Potential registers zp[1]:129 [ idx2#2 idx2#1 ] : zp[1]:129 , reg byte x , reg byte y , +Potential registers zp[1]:130 [ main::i#2 main::i#1 ] : zp[1]:130 , reg byte x , reg byte y , +Potential registers zp[1]:131 [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] : zp[1]:131 , reg byte x , reg byte y , +Potential registers zp[1]:132 [ p0_xpos ] : zp[1]:132 , +Potential registers zp[1]:133 [ p0_ypos#1 ] : zp[1]:133 , reg byte x , reg byte y , +Potential registers zp[1]:134 [ main::gfx#0 ] : zp[1]:134 , reg byte a , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [main] 4,004: mem[1] [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] 2,419.08: mem[1] [ main::i#2 main::i#1 ] 1,501.5: mem[1] [ main::gfx#0 ] -Uplift Scope [] 173.02: mem[1] [ idx#2 idx#1 ] 151.75: mem[1] [ idx2#2 idx2#1 ] 52.48: mem[1] [ p0_ypos#1 ] 2.4: mem[1] [ p0_xpos ] +Uplift Scope [main] 4,004: zp[1]:131 [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] 2,419.08: zp[1]:130 [ main::i#2 main::i#1 ] 1,501.5: zp[1]:134 [ main::gfx#0 ] +Uplift Scope [] 173.02: zp[1]:128 [ idx#2 idx#1 ] 151.75: zp[1]:129 [ idx2#2 idx2#1 ] 52.48: zp[1]:133 [ p0_ypos#1 ] 2.45: zp[1]:132 [ p0_xpos ] Uplift Scope [ATARI_TIA_WRITE] Uplift Scope [ATARI_TIA_READ] Uplift Scope [MOS6532_RIOT] -Uplifting [main] best 13687 combination reg byte y [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::gfx#0 ] -Uplifting [] best 13687 combination mem[1] [ idx#2 idx#1 ] mem[1] [ idx2#2 idx2#1 ] mem[1] [ p0_ypos#1 ] mem[1] [ p0_xpos ] -Uplifting [ATARI_TIA_WRITE] best 13687 combination -Uplifting [ATARI_TIA_READ] best 13687 combination -Uplifting [MOS6532_RIOT] best 13687 combination -Attempting to uplift remaining variables inmem[1] [ idx#2 idx#1 ] -Uplifting [] best 13687 combination mem[1] [ idx#2 idx#1 ] -Attempting to uplift remaining variables inmem[1] [ idx2#2 idx2#1 ] -Uplifting [] best 13687 combination mem[1] [ idx2#2 idx2#1 ] -Attempting to uplift remaining variables inmem[1] [ p0_ypos#1 ] -Uplifting [] best 13687 combination mem[1] [ p0_ypos#1 ] -Attempting to uplift remaining variables inmem[1] [ p0_xpos ] -Uplifting [] best 13687 combination mem[1] [ p0_xpos ] +Uplifting [main] best 13512 combination reg byte y [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::gfx#0 ] +Uplifting [] best 13512 combination zp[1]:128 [ idx#2 idx#1 ] zp[1]:129 [ idx2#2 idx2#1 ] zp[1]:133 [ p0_ypos#1 ] zp[1]:132 [ p0_xpos ] +Uplifting [ATARI_TIA_WRITE] best 13512 combination +Uplifting [ATARI_TIA_READ] best 13512 combination +Uplifting [MOS6532_RIOT] best 13512 combination +Attempting to uplift remaining variables inzp[1]:128 [ idx#2 idx#1 ] +Uplifting [] best 13512 combination zp[1]:128 [ idx#2 idx#1 ] +Attempting to uplift remaining variables inzp[1]:129 [ idx2#2 idx2#1 ] +Uplifting [] best 13512 combination zp[1]:129 [ idx2#2 idx2#1 ] +Attempting to uplift remaining variables inzp[1]:133 [ p0_ypos#1 ] +Uplifting [] best 13512 combination zp[1]:133 [ p0_ypos#1 ] +Attempting to uplift remaining variables inzp[1]:132 [ p0_xpos ] +Uplifting [] best 13512 combination zp[1]:132 [ p0_xpos ] +Allocated (was zp[1]:132) zp[1]:130 [ p0_xpos ] +Allocated (was zp[1]:133) zp[1]:131 [ p0_ypos#1 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -1258,11 +1263,10 @@ ASSEMBLER BEFORE OPTIMIZATION .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors -.word main // NMI -.word main // RESET -.word main // IRQ +.word __bbegin // NMI +.word __bbegin // RESET +.word __bbegin // IRQ .segment Code // Global Constants & labels @@ -1287,8 +1291,18 @@ ASSEMBLER BEFORE OPTIMIZATION .label TIA = 0 // Atari RIOT registers .label RIOT = $280 + .label p0_xpos = $82 + // Counts frames + .label idx = $80 + // Player 0 Y position + .label p0_ypos = $83 + .label idx2 = $81 // @begin __bbegin: + // [0] (byte) p0_xpos ← (byte) 0 -- vbuz1=vbuc1 + // Player 0 X position + lda #0 + sta.z p0_xpos // [1] phi from @begin to @1 [phi:@begin->@1] __b1_from___bbegin: jmp __b1 @@ -1321,12 +1335,12 @@ main: { sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0 // [8] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: - // [8] phi (byte) idx2#2 = (byte) $39 [phi:main->main::@1#0] -- vbum1=vbuc1 + // [8] phi (byte) idx2#2 = (byte) $39 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #$39 - sta idx2 - // [8] phi (byte) idx#2 = (byte) 0 [phi:main->main::@1#1] -- vbum1=vbuc1 + sta.z idx2 + // [8] phi (byte) idx#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1 lda #0 - sta idx + sta.z idx jmp __b1 // main::@1 __b1: @@ -1375,18 +1389,18 @@ main: { asl sta TIA_HMP0 sta TIA_RESP0 - // [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) -- vbum1=pbuc1_derefidx_vbum2 - ldy idx + // [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) -- vbuz1=pbuc1_derefidx_vbuz2 + ldy.z idx lda SINTABLE_160,y - sta p0_xpos - // [17] (byte) idx#1 ← ++ (byte) idx#2 -- vbum1=_inc_vbum1 - inc idx - // [18] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2) -- vbum1=pbuc1_derefidx_vbum2 - ldy idx2 + sta.z p0_xpos + // [17] (byte) idx#1 ← ++ (byte) idx#2 -- vbuz1=_inc_vbuz1 + inc.z idx + // [18] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2) -- vbuz1=pbuc1_derefidx_vbuz2 + ldy.z idx2 lda SINTABLE_160,y - sta p0_ypos - // [19] (byte) idx2#1 ← ++ (byte) idx2#2 -- vbum1=_inc_vbum1 - inc idx2 + sta.z p0_ypos + // [19] (byte) idx2#1 ← ++ (byte) idx2#2 -- vbuz1=_inc_vbuz1 + inc.z idx2 // [20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 -- _deref_pbuc1=vbuc2 // Execute horisontal movement lda #0 @@ -1479,8 +1493,8 @@ main: { jmp __b11 // main::@11 __b11: - // [36] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15 -- vbum1_neq_vbuxx_then_la1 - cpx p0_ypos + // [36] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15 -- vbuz1_neq_vbuxx_then_la1 + cpx.z p0_ypos bne __b15_from___b11 // [38] phi from main::@11 to main::@10 [phi:main::@11->main::@10] __b10_from___b11: @@ -1536,18 +1550,12 @@ main: { } // File Data .segment Data + // Sinus table SINTABLE_160: .fill $100, 10+round(64.5+64.5*sin(2*PI*i/256)) + // The letter C SPRITE_C: .byte 0, $18, $18, $18, $18, $3c, $3c, $3c, $3c, $66, $66, $66, $66, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $66, $66, $66, $66, $3c, $3c, $3c, $3c, $18, $18, $18, $18, 0 -.segment Vars - // Player 0 X position - p0_xpos: .byte 0 - // Counts frames - idx: .byte 0 - // Player 0 Y position - p0_ypos: .byte 0 - idx2: .byte 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __b1 @@ -1574,14 +1582,13 @@ Replacing label __b1 with __b2 Replacing label __b15_from___b11 with __b15 Replacing label __b10_from___b12 with __b15 Removing instruction __b1_from___bbegin: -Removing instruction __b1: Removing instruction __bend_from___b1: Removing instruction __b1: Removing instruction __b15_from___b11: Removing instruction __b10_from___b12: Removing instruction __b10_from___b15: Succesful ASM optimization Pass5RedundantLabelElimination -Removing instruction __bbegin: +Removing instruction __b1: Removing instruction __bend: Removing instruction __b1_from_main: Removing instruction __b5: @@ -1593,13 +1600,13 @@ Removing instruction __b10_from___b11: Removing instruction __b6_from___b10: Removing instruction __b12: Succesful ASM optimization Pass5UnusedLabelElimination -Removing instruction jsr main -Succesful ASM optimization Pass5SkipBegin Skipping double jump to __b10 in bne __b15 Skipping double jump to __b10 in jmp __b15 Succesful ASM optimization Pass5DoubleJumpElimination Relabelling long label __b10_from___b9 to __b1 Succesful ASM optimization Pass5RelabelLongLabels +Adding RTS to root block +Succesful ASM optimization Pass5AddMainRts Removing instruction lda #0 Replacing instruction ldy #0 with TAY Succesful ASM optimization Pass5UnnecesaryLoadElimination @@ -1700,11 +1707,11 @@ FINAL SYMBOL TABLE (const nomodify byte*) TIA_RESP0 = (byte*) 16 (const nomodify byte*) TIA_WSYNC = (byte*) 2 (byte) idx -(byte) idx#1 idx mem[1] 39.357142857142854 -(byte) idx#2 idx mem[1] 133.66666666666669 +(byte) idx#1 idx zp[1]:128 39.357142857142854 +(byte) idx#2 idx zp[1]:128 133.66666666666669 (byte) idx2 -(byte) idx2#1 idx2 mem[1] 42.38461538461539 -(byte) idx2#2 idx2 mem[1] 109.36363636363637 +(byte) idx2#1 idx2 zp[1]:129 42.38461538461539 +(byte) idx2#2 idx2 zp[1]:129 109.36363636363637 (void()) main() (label) main::@1 (label) main::@10 @@ -1730,21 +1737,21 @@ FINAL SYMBOL TABLE (byte) main::p0_idx#3 reg byte y 2002.0 (byte) main::p0_idx#4 reg byte y 500.5 (byte) main::p0_idx#8 reg byte y 1501.5 -(byte) p0_xpos loadstore mem[1] 2.4047619047619047 = (byte) 0 +(byte) p0_xpos loadstore zp[1]:130 2.452380952380952 (byte) p0_ypos -(byte) p0_ypos#1 p0_ypos mem[1] 52.476190476190474 +(byte) p0_ypos#1 p0_ypos zp[1]:131 52.476190476190474 -mem[1] [ idx#2 idx#1 ] -mem[1] [ idx2#2 idx2#1 ] +zp[1]:128 [ idx#2 idx#1 ] +zp[1]:129 [ idx2#2 idx2#1 ] reg byte x [ main::i#2 main::i#1 ] reg byte y [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] -mem[1] [ p0_xpos ] -mem[1] [ p0_ypos#1 ] +zp[1]:130 [ p0_xpos ] +zp[1]:131 [ p0_ypos#1 ] reg byte a [ main::gfx#0 ] FINAL ASSEMBLER -Score: 11035 +Score: 10872 // File Comments // Minimal Atari 2600 VCS Program using Sprites @@ -1755,11 +1762,10 @@ Score: 11035 .segmentdef Code [start=$f800,min=$f800,max=$fff9] .segmentdef Data [startAfter="Code",max=$fff9] .segmentdef Vectors [start=$fffa,max=$ffff] -.segmentdef Vars [start=$80,max=$ff, virtual] .segment Vectors -.word main // NMI -.word main // RESET -.word main // IRQ +.word __bbegin // NMI +.word __bbegin // RESET +.word __bbegin // IRQ .segment Code // Global Constants & labels @@ -1784,10 +1790,24 @@ Score: 11035 .label TIA = 0 // Atari RIOT registers .label RIOT = $280 + .label p0_xpos = $82 + // Counts frames + .label idx = $80 + // Player 0 Y position + .label p0_ypos = $83 + .label idx2 = $81 // @begin +__bbegin: + // p0_xpos + // [0] (byte) p0_xpos ← (byte) 0 -- vbuz1=vbuc1 + // Player 0 X position + lda #0 + sta.z p0_xpos // [1] phi from @begin to @1 [phi:@begin->@1] // @1 // [2] call main + jsr main + rts // [3] phi from @1 to @end [phi:@1->@end] // @end .segment Code @@ -1813,12 +1833,12 @@ main: { lda #5 sta TIA+OFFSET_STRUCT_ATARI_TIA_WRITE_NUSIZ0 // [8] phi from main to main::@1 [phi:main->main::@1] - // [8] phi (byte) idx2#2 = (byte) $39 [phi:main->main::@1#0] -- vbum1=vbuc1 + // [8] phi (byte) idx2#2 = (byte) $39 [phi:main->main::@1#0] -- vbuz1=vbuc1 lda #$39 - sta idx2 - // [8] phi (byte) idx#2 = (byte) 0 [phi:main->main::@1#1] -- vbum1=vbuc1 + sta.z idx2 + // [8] phi (byte) idx#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1 lda #0 - sta idx + sta.z idx // main::@1 // main::@2 __b2: @@ -1867,21 +1887,21 @@ main: { sta TIA_HMP0 sta TIA_RESP0 // p0_xpos = SINTABLE_160[idx++] - // [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) -- vbum1=pbuc1_derefidx_vbum2 - ldy idx + // [16] (byte) p0_xpos ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx#2) -- vbuz1=pbuc1_derefidx_vbuz2 + ldy.z idx lda SINTABLE_160,y - sta p0_xpos + sta.z p0_xpos // p0_xpos = SINTABLE_160[idx++]; - // [17] (byte) idx#1 ← ++ (byte) idx#2 -- vbum1=_inc_vbum1 - inc idx + // [17] (byte) idx#1 ← ++ (byte) idx#2 -- vbuz1=_inc_vbuz1 + inc.z idx // p0_ypos = SINTABLE_160[idx2++] - // [18] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2) -- vbum1=pbuc1_derefidx_vbum2 - ldy idx2 + // [18] (byte) p0_ypos#1 ← *((const to_nomodify byte*) SINTABLE_160 + (byte) idx2#2) -- vbuz1=pbuc1_derefidx_vbuz2 + ldy.z idx2 lda SINTABLE_160,y - sta p0_ypos + sta.z p0_ypos // p0_ypos = SINTABLE_160[idx2++]; - // [19] (byte) idx2#1 ← ++ (byte) idx2#2 -- vbum1=_inc_vbum1 - inc idx2 + // [19] (byte) idx2#1 ← ++ (byte) idx2#2 -- vbuz1=_inc_vbuz1 + inc.z idx2 // TIA->WSYNC = 0 // [20] *((byte*)(const nomodify struct ATARI_TIA_WRITE*) TIA+(const byte) OFFSET_STRUCT_ATARI_TIA_WRITE_WSYNC) ← (byte) 0 -- _deref_pbuc1=vbuc2 // Execute horisontal movement @@ -1975,8 +1995,8 @@ main: { bne __b9 // main::@11 // if(p0_ypos==i) - // [36] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15 -- vbum1_neq_vbuxx_then_la1 - cpx p0_ypos + // [36] if((byte) p0_ypos#1!=(byte) main::i#2) goto main::@15 -- vbuz1_neq_vbuxx_then_la1 + cpx.z p0_ypos bne __b10 // [38] phi from main::@11 to main::@10 [phi:main::@11->main::@10] // [38] phi (byte) main::p0_idx#8 = (byte) 1 [phi:main::@11->main::@10#0] -- vbuyy=vbuc1 @@ -2027,16 +2047,10 @@ main: { } // File Data .segment Data + // Sinus table SINTABLE_160: .fill $100, 10+round(64.5+64.5*sin(2*PI*i/256)) + // The letter C SPRITE_C: .byte 0, $18, $18, $18, $18, $3c, $3c, $3c, $3c, $66, $66, $66, $66, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0, $66, $66, $66, $66, $3c, $3c, $3c, $3c, $18, $18, $18, $18, 0 -.segment Vars - // Player 0 X position - p0_xpos: .byte 0 - // Counts frames - idx: .byte 0 - // Player 0 Y position - p0_ypos: .byte 0 - idx2: .byte 0 diff --git a/src/test/ref/examples/atari2600/atari2600-sprites.sym b/src/test/ref/examples/atari2600/atari2600-sprites.sym index 9db22a4b7..67f1d20a0 100644 --- a/src/test/ref/examples/atari2600/atari2600-sprites.sym +++ b/src/test/ref/examples/atari2600/atari2600-sprites.sym @@ -89,11 +89,11 @@ (const nomodify byte*) TIA_RESP0 = (byte*) 16 (const nomodify byte*) TIA_WSYNC = (byte*) 2 (byte) idx -(byte) idx#1 idx mem[1] 39.357142857142854 -(byte) idx#2 idx mem[1] 133.66666666666669 +(byte) idx#1 idx zp[1]:128 39.357142857142854 +(byte) idx#2 idx zp[1]:128 133.66666666666669 (byte) idx2 -(byte) idx2#1 idx2 mem[1] 42.38461538461539 -(byte) idx2#2 idx2 mem[1] 109.36363636363637 +(byte) idx2#1 idx2 zp[1]:129 42.38461538461539 +(byte) idx2#2 idx2 zp[1]:129 109.36363636363637 (void()) main() (label) main::@1 (label) main::@10 @@ -119,14 +119,14 @@ (byte) main::p0_idx#3 reg byte y 2002.0 (byte) main::p0_idx#4 reg byte y 500.5 (byte) main::p0_idx#8 reg byte y 1501.5 -(byte) p0_xpos loadstore mem[1] 2.4047619047619047 = (byte) 0 +(byte) p0_xpos loadstore zp[1]:130 2.452380952380952 (byte) p0_ypos -(byte) p0_ypos#1 p0_ypos mem[1] 52.476190476190474 +(byte) p0_ypos#1 p0_ypos zp[1]:131 52.476190476190474 -mem[1] [ idx#2 idx#1 ] -mem[1] [ idx2#2 idx2#1 ] +zp[1]:128 [ idx#2 idx#1 ] +zp[1]:129 [ idx2#2 idx2#1 ] reg byte x [ main::i#2 main::i#1 ] reg byte y [ main::p0_idx#4 main::p0_idx#8 main::p0_idx#3 ] -mem[1] [ p0_xpos ] -mem[1] [ p0_ypos#1 ] +zp[1]:130 [ p0_xpos ] +zp[1]:131 [ p0_ypos#1 ] reg byte a [ main::gfx#0 ]