From 70f0d841b59ae53d612182afd1219e9c630f2219 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Mon, 24 Aug 2020 01:21:18 +0200 Subject: [PATCH] Added MEGA65 conio.c constructor. And "Hello World" program. #507 --- src/main/kc/lib/conio-mega65.c | 25 + .../dk/camelot64/kickc/test/TestPrograms.java | 5 + .../kc/examples/mega65/helloworld-mega65.c | 7 + .../ref/examples/mega65/helloworld-mega65.asm | 303 ++ .../ref/examples/mega65/helloworld-mega65.cfg | 165 + .../ref/examples/mega65/helloworld-mega65.log | 3024 +++++++++++++++++ .../ref/examples/mega65/helloworld-mega65.sym | 191 ++ 7 files changed, 3720 insertions(+) create mode 100644 src/test/kc/examples/mega65/helloworld-mega65.c create mode 100644 src/test/ref/examples/mega65/helloworld-mega65.asm create mode 100644 src/test/ref/examples/mega65/helloworld-mega65.cfg create mode 100644 src/test/ref/examples/mega65/helloworld-mega65.log create mode 100644 src/test/ref/examples/mega65/helloworld-mega65.sym diff --git a/src/main/kc/lib/conio-mega65.c b/src/main/kc/lib/conio-mega65.c index c03eeefb7..8cf5eb4eb 100644 --- a/src/main/kc/lib/conio-mega65.c +++ b/src/main/kc/lib/conio-mega65.c @@ -16,6 +16,31 @@ const char CONIO_TEXTCOLOR_DEFAULT = LIGHT_BLUE; // Use the shared CBM flat memory implementation #include "conio-cbm-shared.c" +// Initializer for conio.h on MEGA65 +#pragma constructor_for(conio_mega65_init, cputc) + +// Enable 2K Color ROM +void conio_mega65_init() { + // Disable BASIC/KERNAL interrupts + asm { + sei + } + // Map memory to BANK 0 : 0x00XXXX - giving access to I/O + asm { + lda #0 + tax + tay + taz + map + eom + } + // Enable the VIC 4 + *IO_KEY = 0x47; + *IO_KEY = 0x53; + // Enable 2K Color RAM + *IO_BANK |= CRAM2K; +} + // Return true if there's a key waiting, return false if not unsigned char kbhit (void) { // CIA#1 Port A: keyboard matrix columns and joystick #2 diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 0f682a8ab..d96f168fb 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -212,6 +212,11 @@ public class TestPrograms { compileAndCompare("examples/mega65/32bit-addressing-mega65.c"); } + @Test + public void testMega65HelloWorld() throws IOException, URISyntaxException { + compileAndCompare("examples/mega65/helloworld-mega65.c"); + } + @Test public void testMega65Hello() throws IOException, URISyntaxException { compileAndCompare("examples/mega65/hello-mega65.c"); diff --git a/src/test/kc/examples/mega65/helloworld-mega65.c b/src/test/kc/examples/mega65/helloworld-mega65.c new file mode 100644 index 000000000..21a44bd01 --- /dev/null +++ b/src/test/kc/examples/mega65/helloworld-mega65.c @@ -0,0 +1,7 @@ +// Hello World for MEGA 65 - using stdio.h and conio.h +#pragma target(mega65) +#include + +void main() { + printf("hello world!"); +} \ No newline at end of file diff --git a/src/test/ref/examples/mega65/helloworld-mega65.asm b/src/test/ref/examples/mega65/helloworld-mega65.asm new file mode 100644 index 000000000..a38ad6782 --- /dev/null +++ b/src/test/ref/examples/mega65/helloworld-mega65.asm @@ -0,0 +1,303 @@ +// Hello World for MEGA 65 - using stdio.h and conio.h +// Functions for performing input and output. +.cpu _45gs02 + .file [name="helloworld-mega65.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$2001] +.segmentdef Code [start=$2017] +.segmentdef Data [startAfter="Code"] +.segment Basic +.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0 +.byte $15, $20, $14, $00, $9e, $20 // 20 SYS +.text toIntString(__start) // NNNN +.byte $00, $00, $00 // + // Map 2nd KB of colour RAM $DC00-$DFFF (hiding CIA's) + .const CRAM2K = 1 + .const LIGHT_BLUE = $e + // I/O Personality selection + .label IO_KEY = $d02f + // C65 Banking Register + .label IO_BANK = $d030 + // Color Ram + .label COLORRAM = $d800 + // Default address of screen character matrix + .label DEFAULT_SCREEN = $800 + // The number of bytes on the screen + // The current cursor x-position + .label conio_cursor_x = 6 + // The current cursor y-position + .label conio_cursor_y = 7 + // The current text cursor line start + .label conio_line_text = 8 + // The current color cursor line start + .label conio_line_color = $a +.segment Code +__start: { + // conio_cursor_x = 0 + lda #0 + sta.z conio_cursor_x + // conio_cursor_y = 0 + sta.z conio_cursor_y + // conio_line_text = CONIO_SCREEN_TEXT + lda #DEFAULT_SCREEN + sta.z conio_line_text+1 + // conio_line_color = CONIO_SCREEN_COLORS + lda #COLORRAM + sta.z conio_line_color+1 + // #pragma constructor_for(conio_mega65_init, cputc) + //#pragma constructor + jsr conio_mega65_init + jsr main + rts +} +// Enable 2K Color ROM +conio_mega65_init: { + // asm + // Disable BASIC/KERNAL interrupts + sei + // Map memory to BANK 0 : 0x00XXXX - giving access to I/O + lda #0 + tax + tay + taz + map + eom + // *IO_KEY = 0x47 + // Enable the VIC 4 + lda #$47 + sta IO_KEY + // *IO_KEY = 0x53 + lda #$53 + sta IO_KEY + // *IO_BANK |= CRAM2K + // Enable 2K Color RAM + lda #CRAM2K + ora IO_BANK + sta IO_BANK + // } + rts +} +main: { + // printf("hello world!") + jsr cputs + // } + rts + .segment Data + s: .text "hello world!" + .byte 0 +} +.segment Code +// Output a NUL-terminated string at the current cursor position +// cputs(byte* zp(2) s) +cputs: { + .label s = 2 + lda #main.s + sta.z s+1 + __b1: + // while(c=*s++) + ldy #0 + lda (s),y + inw.z s + cmp #0 + bne __b2 + // } + rts + __b2: + // cputc(c) + jsr cputc + jmp __b1 +} +// Output one character at the current cursor position +// Moves the cursor forward. Scrolls the entire screen if needed +// cputc(byte register(A) c) +cputc: { + // if(c=='\n') + cmp #'\n' + beq __b1 + // conio_line_text[conio_cursor_x] = c + ldy.z conio_cursor_x + sta (conio_line_text),y + // conio_line_color[conio_cursor_x] = conio_textcolor + lda #LIGHT_BLUE + sta (conio_line_color),y + // if(++conio_cursor_x==CONIO_WIDTH) + inc.z conio_cursor_x + lda #$50 + cmp.z conio_cursor_x + bne __breturn + // cputln() + jsr cputln + __breturn: + // } + rts + __b1: + // cputln() + jsr cputln + rts +} +// Print a newline +cputln: { + // conio_line_text += CONIO_WIDTH + lda #$50 + clc + adc.z conio_line_text + sta.z conio_line_text + bcc !+ + inc.z conio_line_text+1 + !: + // conio_line_color += CONIO_WIDTH + lda #$50 + clc + adc.z conio_line_color + sta.z conio_line_color + bcc !+ + inc.z conio_line_color+1 + !: + // conio_cursor_x = 0 + lda #0 + sta.z conio_cursor_x + // conio_cursor_y++; + inc.z conio_cursor_y + // cscroll() + jsr cscroll + // } + rts +} +// Scroll the entire screen if the cursor is beyond the last line +cscroll: { + // if(conio_cursor_y==CONIO_HEIGHT) + lda #$19 + cmp.z conio_cursor_y + bne __breturn + // memcpy(CONIO_SCREEN_TEXT, CONIO_SCREEN_TEXT+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH) + lda #DEFAULT_SCREEN + sta.z memcpy.destination+1 + lda #DEFAULT_SCREEN+$50 + sta.z memcpy.source+1 + jsr memcpy + // memcpy(CONIO_SCREEN_COLORS, CONIO_SCREEN_COLORS+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH) + lda #COLORRAM + sta.z memcpy.destination+1 + lda #COLORRAM+$50 + sta.z memcpy.source+1 + jsr memcpy + // memset(CONIO_SCREEN_TEXT+CONIO_BYTES-CONIO_WIDTH, ' ', CONIO_WIDTH) + ldz #' ' + lda #DEFAULT_SCREEN+$19*$50-$50 + sta.z memset.str+1 + jsr memset + // memset(CONIO_SCREEN_COLORS+CONIO_BYTES-CONIO_WIDTH, conio_textcolor, CONIO_WIDTH) + ldz #LIGHT_BLUE + lda #COLORRAM+$19*$50-$50 + sta.z memset.str+1 + jsr memset + // conio_line_text -= CONIO_WIDTH + sec + lda.z conio_line_text + sbc #$50 + sta.z conio_line_text + lda.z conio_line_text+1 + sbc #0 + sta.z conio_line_text+1 + // conio_line_color -= CONIO_WIDTH + sec + lda.z conio_line_color + sbc #$50 + sta.z conio_line_color + lda.z conio_line_color+1 + sbc #0 + sta.z conio_line_color+1 + // conio_cursor_y--; + dec.z conio_cursor_y + __breturn: + // } + rts +} +// Copy block of memory (forwards) +// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. +// memcpy(void* zp($e) destination, void* zp(4) source) +memcpy: { + .label src_end = $c + .label dst = $e + .label src = 4 + .label source = 4 + .label destination = $e + // src_end = (char*)source+num + lda.z source + clc + adc #<$19*$50-$50 + sta.z src_end + lda.z source+1 + adc #>$19*$50-$50 + sta.z src_end+1 + __b1: + // while(src!=src_end) + lda.z src+1 + cmp.z src_end+1 + bne __b2 + lda.z src + cmp.z src_end + bne __b2 + // } + rts + __b2: + // *dst++ = *src++ + ldy #0 + lda (src),y + sta (dst),y + // *dst++ = *src++; + inw.z dst + inw.z src + jmp __b1 +} +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +// memset(void* zp(4) str, byte register(Z) c) +memset: { + .label end = $e + .label dst = 4 + .label str = 4 + // end = (char*)str + num + lda #$50 + clc + adc.z str + sta.z end + lda #0 + adc.z str+1 + sta.z end+1 + __b2: + // for(char* dst = str; dst!=end; dst++) + lda.z dst+1 + cmp.z end+1 + bne __b3 + lda.z dst + cmp.z end + bne __b3 + // } + rts + __b3: + // *dst = c + tza + ldy #0 + sta (dst),y + // for(char* dst = str; dst!=end; dst++) + inw.z dst + jmp __b2 +} diff --git a/src/test/ref/examples/mega65/helloworld-mega65.cfg b/src/test/ref/examples/mega65/helloworld-mega65.cfg new file mode 100644 index 000000000..3627d3c24 --- /dev/null +++ b/src/test/ref/examples/mega65/helloworld-mega65.cfg @@ -0,0 +1,165 @@ + +(void()) __start() +__start: scope:[__start] from + [0] phi() + to:__start::__init1 +__start::__init1: scope:[__start] from __start + [1] (byte) conio_cursor_x ← (byte) 0 + [2] (byte) conio_cursor_y ← (byte) 0 + [3] (byte*) conio_line_text ← (const nomodify byte*) DEFAULT_SCREEN + [4] (byte*) conio_line_color ← (const nomodify byte*) COLORRAM + [5] call conio_mega65_init + to:__start::@1 +__start::@1: scope:[__start] from __start::__init1 + [6] phi() + [7] call main + to:__start::@return +__start::@return: scope:[__start] from __start::@1 + [8] return + to:@return + +(void()) conio_mega65_init() +conio_mega65_init: scope:[conio_mega65_init] from __start::__init1 + asm { sei } + asm { lda#0 tax tay taz map eom } + [11] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $47 + [12] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $53 + [13] *((const nomodify to_volatile byte*) IO_BANK) ← *((const nomodify to_volatile byte*) IO_BANK) | (const nomodify byte) CRAM2K + to:conio_mega65_init::@return +conio_mega65_init::@return: scope:[conio_mega65_init] from conio_mega65_init + [14] return + to:@return + +(void()) main() +main: scope:[main] from __start::@1 + [15] phi() + [16] call cputs + to:main::@return +main::@return: scope:[main] from main + [17] return + to:@return + +(void()) cputs((to_nomodify byte*) cputs::s) +cputs: scope:[cputs] from main + [18] phi() + to:cputs::@1 +cputs::@1: scope:[cputs] from cputs cputs::@2 + [19] (to_nomodify byte*) cputs::s#2 ← phi( cputs/(const byte*) main::s cputs::@2/(to_nomodify byte*) cputs::s#0 ) + [20] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2) + [21] (to_nomodify byte*) cputs::s#0 ← ++ (to_nomodify byte*) cputs::s#2 + [22] if((byte) 0!=(byte) cputs::c#1) goto cputs::@2 + to:cputs::@return +cputs::@return: scope:[cputs] from cputs::@1 + [23] return + to:@return +cputs::@2: scope:[cputs] from cputs::@1 + [24] (byte) cputc::c#0 ← (byte) cputs::c#1 + [25] call cputc + to:cputs::@1 + +(void()) cputc((byte) cputc::c) +cputc: scope:[cputc] from cputs::@2 + [26] if((byte) cputc::c#0==(byte) ' +') goto cputc::@1 + to:cputc::@2 +cputc::@2: scope:[cputc] from cputc + [27] *((byte*) conio_line_text + (byte) conio_cursor_x) ← (byte) cputc::c#0 + [28] *((byte*) conio_line_color + (byte) conio_cursor_x) ← (const nomodify byte) LIGHT_BLUE + [29] (byte) conio_cursor_x ← ++ (byte) conio_cursor_x + [30] if((byte) conio_cursor_x!=(byte) $50) goto cputc::@return + to:cputc::@3 +cputc::@3: scope:[cputc] from cputc::@2 + [31] phi() + [32] call cputln + to:cputc::@return +cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@3 + [33] return + to:@return +cputc::@1: scope:[cputc] from cputc + [34] phi() + [35] call cputln + to:cputc::@return + +(void()) cputln() +cputln: scope:[cputln] from cputc::@1 cputc::@3 + [36] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $50 + [37] (byte*) conio_line_color ← (byte*) conio_line_color + (byte) $50 + [38] (byte) conio_cursor_x ← (byte) 0 + [39] (byte) conio_cursor_y ← ++ (byte) conio_cursor_y + [40] call cscroll + to:cputln::@return +cputln::@return: scope:[cputln] from cputln + [41] return + to:@return + +(void()) cscroll() +cscroll: scope:[cscroll] from cputln + [42] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return + to:cscroll::@1 +cscroll::@1: scope:[cscroll] from cscroll + [43] phi() + [44] call memcpy + to:cscroll::@2 +cscroll::@2: scope:[cscroll] from cscroll::@1 + [45] phi() + [46] call memcpy + to:cscroll::@3 +cscroll::@3: scope:[cscroll] from cscroll::@2 + [47] phi() + [48] call memset + to:cscroll::@4 +cscroll::@4: scope:[cscroll] from cscroll::@3 + [49] phi() + [50] call memset + to:cscroll::@5 +cscroll::@5: scope:[cscroll] from cscroll::@4 + [51] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $50 + [52] (byte*) conio_line_color ← (byte*) conio_line_color - (byte) $50 + [53] (byte) conio_cursor_y ← -- (byte) conio_cursor_y + to:cscroll::@return +cscroll::@return: scope:[cscroll] from cscroll cscroll::@5 + [54] return + to:@return + +(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num) +memcpy: scope:[memcpy] from cscroll::@1 cscroll::@2 + [55] (void*) memcpy::destination#2 ← phi( cscroll::@1/(void*)(const nomodify byte*) DEFAULT_SCREEN cscroll::@2/(void*)(const nomodify byte*) COLORRAM ) + [55] (void*) memcpy::source#2 ← phi( cscroll::@1/(void*)(const nomodify byte*) DEFAULT_SCREEN+(byte) $50 cscroll::@2/(void*)(const nomodify byte*) COLORRAM+(byte) $50 ) + [56] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word)(number) $19*(number) $50-(number) $50 + [57] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 + [58] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 + to:memcpy::@1 +memcpy::@1: scope:[memcpy] from memcpy memcpy::@2 + [59] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#4 memcpy::@2/(byte*) memcpy::dst#1 ) + [59] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#4 memcpy::@2/(byte*) memcpy::src#1 ) + [60] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 + to:memcpy::@return +memcpy::@return: scope:[memcpy] from memcpy::@1 + [61] return + to:@return +memcpy::@2: scope:[memcpy] from memcpy::@1 + [62] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) + [63] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 + [64] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 + to:memcpy::@1 + +(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num) +memset: scope:[memset] from cscroll::@3 cscroll::@4 + [65] (byte) memset::c#4 ← phi( cscroll::@3/(byte) ' ' cscroll::@4/(const nomodify byte) LIGHT_BLUE ) + [65] (void*) memset::str#3 ← phi( cscroll::@3/(void*)(const nomodify byte*) DEFAULT_SCREEN+(word)(number) $19*(number) $50-(byte) $50 cscroll::@4/(void*)(const nomodify byte*) COLORRAM+(word)(number) $19*(number) $50-(byte) $50 ) + to:memset::@1 +memset::@1: scope:[memset] from memset + [66] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (byte) $50 + [67] (byte*) memset::dst#4 ← (byte*)(void*) memset::str#3 + to:memset::@2 +memset::@2: scope:[memset] from memset::@1 memset::@3 + [68] (byte*) memset::dst#2 ← phi( memset::@1/(byte*) memset::dst#4 memset::@3/(byte*) memset::dst#1 ) + [69] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3 + to:memset::@return +memset::@return: scope:[memset] from memset::@2 + [70] return + to:@return +memset::@3: scope:[memset] from memset::@2 + [71] *((byte*) memset::dst#2) ← (byte) memset::c#4 + [72] (byte*) memset::dst#1 ← ++ (byte*) memset::dst#2 + to:memset::@2 diff --git a/src/test/ref/examples/mega65/helloworld-mega65.log b/src/test/ref/examples/mega65/helloworld-mega65.log new file mode 100644 index 000000000..ba7f6277a --- /dev/null +++ b/src/test/ref/examples/mega65/helloworld-mega65.log @@ -0,0 +1,3024 @@ +Fixing struct type size struct printf_buffer_number to 12 +Fixing struct type size struct printf_buffer_number to 12 +Fixing struct type SIZE_OF struct printf_buffer_number to 12 +Fixing struct type SIZE_OF struct printf_buffer_number to 12 +Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx +Inlined call call __init +Eliminating unused variable with no statement (struct printf_buffer_number) printf_buffer +Eliminating unused variable with no statement (void~) main::$0 + +CONTROL FLOW GRAPH SSA + +(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num) +memcpy: scope:[memcpy] from cscroll::@3 cscroll::@4 + (word) memcpy::num#2 ← phi( cscroll::@3/(word) memcpy::num#0 cscroll::@4/(word) memcpy::num#1 ) + (void*) memcpy::destination#2 ← phi( cscroll::@3/(void*) memcpy::destination#0 cscroll::@4/(void*) memcpy::destination#1 ) + (void*) memcpy::source#2 ← phi( cscroll::@3/(void*) memcpy::source#0 cscroll::@4/(void*) memcpy::source#1 ) + (byte*) memcpy::src#0 ← ((byte*)) (void*) memcpy::source#2 + (byte*) memcpy::dst#0 ← ((byte*)) (void*) memcpy::destination#2 + (byte*~) memcpy::$2 ← (byte*)(void*) memcpy::source#2 + (byte*~) memcpy::$0 ← (byte*~) memcpy::$2 + (word) memcpy::num#2 + (byte*) memcpy::src_end#0 ← (byte*~) memcpy::$0 + to:memcpy::@1 +memcpy::@1: scope:[memcpy] from memcpy memcpy::@2 + (void*) memcpy::destination#4 ← phi( memcpy/(void*) memcpy::destination#2 memcpy::@2/(void*) memcpy::destination#5 ) + (byte*) memcpy::dst#3 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@2/(byte*) memcpy::dst#1 ) + (byte*) memcpy::src_end#1 ← phi( memcpy/(byte*) memcpy::src_end#0 memcpy::@2/(byte*) memcpy::src_end#2 ) + (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@2/(byte*) memcpy::src#1 ) + (bool~) memcpy::$1 ← (byte*) memcpy::src#2 != (byte*) memcpy::src_end#1 + if((bool~) memcpy::$1) goto memcpy::@2 + to:memcpy::@3 +memcpy::@2: scope:[memcpy] from memcpy::@1 + (void*) memcpy::destination#5 ← phi( memcpy::@1/(void*) memcpy::destination#4 ) + (byte*) memcpy::src_end#2 ← phi( memcpy::@1/(byte*) memcpy::src_end#1 ) + (byte*) memcpy::dst#2 ← phi( memcpy::@1/(byte*) memcpy::dst#3 ) + (byte*) memcpy::src#3 ← phi( memcpy::@1/(byte*) memcpy::src#2 ) + *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#3) + (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 + (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#3 + to:memcpy::@1 +memcpy::@3: scope:[memcpy] from memcpy::@1 + (void*) memcpy::destination#3 ← phi( memcpy::@1/(void*) memcpy::destination#4 ) + (void*) memcpy::return#0 ← (void*) memcpy::destination#3 + to:memcpy::@return +memcpy::@return: scope:[memcpy] from memcpy::@3 + (void*) memcpy::return#4 ← phi( memcpy::@3/(void*) memcpy::return#0 ) + (void*) memcpy::return#1 ← (void*) memcpy::return#4 + return + to:@return + +(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num) +memset: scope:[memset] from cscroll::@5 cscroll::@6 + (byte) memset::c#5 ← phi( cscroll::@5/(byte) memset::c#0 cscroll::@6/(byte) memset::c#1 ) + (void*) memset::str#4 ← phi( cscroll::@5/(void*) memset::str#0 cscroll::@6/(void*) memset::str#1 ) + (word) memset::num#2 ← phi( cscroll::@5/(word) memset::num#0 cscroll::@6/(word) memset::num#1 ) + (bool~) memset::$0 ← (word) memset::num#2 > (number) 0 + (bool~) memset::$1 ← ! (bool~) memset::$0 + if((bool~) memset::$1) goto memset::@1 + to:memset::@2 +memset::@1: scope:[memset] from memset memset::@3 + (void*) memset::str#2 ← phi( memset/(void*) memset::str#4 memset::@3/(void*) memset::str#5 ) + (void*) memset::return#0 ← (void*) memset::str#2 + to:memset::@return +memset::@2: scope:[memset] from memset + (byte) memset::c#4 ← phi( memset/(byte) memset::c#5 ) + (word) memset::num#3 ← phi( memset/(word) memset::num#2 ) + (void*) memset::str#3 ← phi( memset/(void*) memset::str#4 ) + (byte*~) memset::$4 ← (byte*)(void*) memset::str#3 + (byte*~) memset::$2 ← (byte*~) memset::$4 + (word) memset::num#3 + (byte*) memset::end#0 ← (byte*~) memset::$2 + (byte*) memset::dst#0 ← ((byte*)) (void*) memset::str#3 + to:memset::@3 +memset::@3: scope:[memset] from memset::@2 memset::@4 + (byte) memset::c#3 ← phi( memset::@2/(byte) memset::c#4 memset::@4/(byte) memset::c#2 ) + (void*) memset::str#5 ← phi( memset::@2/(void*) memset::str#3 memset::@4/(void*) memset::str#6 ) + (byte*) memset::end#1 ← phi( memset::@2/(byte*) memset::end#0 memset::@4/(byte*) memset::end#2 ) + (byte*) memset::dst#2 ← phi( memset::@2/(byte*) memset::dst#0 memset::@4/(byte*) memset::dst#1 ) + (bool~) memset::$3 ← (byte*) memset::dst#2 != (byte*) memset::end#1 + if((bool~) memset::$3) goto memset::@4 + to:memset::@1 +memset::@4: scope:[memset] from memset::@3 + (void*) memset::str#6 ← phi( memset::@3/(void*) memset::str#5 ) + (byte*) memset::end#2 ← phi( memset::@3/(byte*) memset::end#1 ) + (byte*) memset::dst#3 ← phi( memset::@3/(byte*) memset::dst#2 ) + (byte) memset::c#2 ← phi( memset::@3/(byte) memset::c#3 ) + *((byte*) memset::dst#3) ← (byte) memset::c#2 + (byte*) memset::dst#1 ← ++ (byte*) memset::dst#3 + to:memset::@3 +memset::@return: scope:[memset] from memset::@1 + (void*) memset::return#4 ← phi( memset::@1/(void*) memset::return#0 ) + (void*) memset::return#1 ← (void*) memset::return#4 + return + to:@return + +(void()) gotoxy((byte) gotoxy::x , (byte) gotoxy::y) +gotoxy: scope:[gotoxy] from cscroll::@2 + (byte) gotoxy::x#4 ← phi( cscroll::@2/(byte) gotoxy::x#1 ) + (byte) gotoxy::y#2 ← phi( cscroll::@2/(byte) gotoxy::y#1 ) + (bool~) gotoxy::$0 ← (byte) gotoxy::y#2 > (number) $19 + (bool~) gotoxy::$1 ← ! (bool~) gotoxy::$0 + if((bool~) gotoxy::$1) goto gotoxy::@1 + to:gotoxy::@3 +gotoxy::@1: scope:[gotoxy] from gotoxy gotoxy::@3 + (byte) gotoxy::y#4 ← phi( gotoxy/(byte) gotoxy::y#2 gotoxy::@3/(byte) gotoxy::y#0 ) + (byte) gotoxy::x#2 ← phi( gotoxy/(byte) gotoxy::x#4 gotoxy::@3/(byte) gotoxy::x#5 ) + (bool~) gotoxy::$2 ← (byte) gotoxy::x#2 >= (number) $50 + (bool~) gotoxy::$3 ← ! (bool~) gotoxy::$2 + if((bool~) gotoxy::$3) goto gotoxy::@2 + to:gotoxy::@4 +gotoxy::@3: scope:[gotoxy] from gotoxy + (byte) gotoxy::x#5 ← phi( gotoxy/(byte) gotoxy::x#4 ) + (byte) gotoxy::y#0 ← (number) 0 + to:gotoxy::@1 +gotoxy::@2: scope:[gotoxy] from gotoxy::@1 gotoxy::@4 + (byte) gotoxy::y#3 ← phi( gotoxy::@1/(byte) gotoxy::y#4 gotoxy::@4/(byte) gotoxy::y#5 ) + (byte) gotoxy::x#3 ← phi( gotoxy::@1/(byte) gotoxy::x#2 gotoxy::@4/(byte) gotoxy::x#0 ) + (byte) conio_cursor_x ← (byte) gotoxy::x#3 + (byte) conio_cursor_y ← (byte) gotoxy::y#3 + (word~) gotoxy::$7 ← (word)(byte) gotoxy::y#3 + (number~) gotoxy::$4 ← (word~) gotoxy::$7 * (number) $50 + (word) gotoxy::line_offset#0 ← (number~) gotoxy::$4 + (byte*~) gotoxy::$5 ← (const nomodify byte*) CONIO_SCREEN_TEXT + (word) gotoxy::line_offset#0 + (byte*) conio_line_text ← (byte*~) gotoxy::$5 + (byte*~) gotoxy::$6 ← (const nomodify byte*) CONIO_SCREEN_COLORS + (word) gotoxy::line_offset#0 + (byte*) conio_line_color ← (byte*~) gotoxy::$6 + to:gotoxy::@return +gotoxy::@4: scope:[gotoxy] from gotoxy::@1 + (byte) gotoxy::y#5 ← phi( gotoxy::@1/(byte) gotoxy::y#4 ) + (byte) gotoxy::x#0 ← (number) 0 + to:gotoxy::@2 +gotoxy::@return: scope:[gotoxy] from gotoxy::@2 + return + to:@return + +(void()) cputc((byte) cputc::c) +cputc: scope:[cputc] from cputs::@2 + (byte) cputc::c#1 ← phi( cputs::@2/(byte) cputc::c#0 ) + (bool~) cputc::$0 ← (byte) cputc::c#1 == (byte) ' +' + if((bool~) cputc::$0) goto cputc::@1 + to:cputc::@2 +cputc::@1: scope:[cputc] from cputc + call cputln + to:cputc::@4 +cputc::@4: scope:[cputc] from cputc::@1 + to:cputc::@return +cputc::@2: scope:[cputc] from cputc + (byte) cputc::c#2 ← phi( cputc/(byte) cputc::c#1 ) + *((byte*) conio_line_text + (byte) conio_cursor_x) ← (byte) cputc::c#2 + *((byte*) conio_line_color + (byte) conio_cursor_x) ← (byte) conio_textcolor + (byte) conio_cursor_x ← ++ (byte) conio_cursor_x + (bool~) cputc::$1 ← (byte) conio_cursor_x == (number) $50 + (bool~) cputc::$2 ← ! (bool~) cputc::$1 + if((bool~) cputc::$2) goto cputc::@return + to:cputc::@3 +cputc::@3: scope:[cputc] from cputc::@2 + call cputln + to:cputc::@5 +cputc::@5: scope:[cputc] from cputc::@3 + to:cputc::@return +cputc::@return: scope:[cputc] from cputc::@2 cputc::@4 cputc::@5 + return + to:@return + +(void()) cputln() +cputln: scope:[cputln] from cputc::@1 cputc::@3 + (byte*) conio_line_text ← (byte*) conio_line_text + (number) $50 + (byte*) conio_line_color ← (byte*) conio_line_color + (number) $50 + (byte) conio_cursor_x ← (number) 0 + (byte) conio_cursor_y ← ++ (byte) conio_cursor_y + call cscroll + to:cputln::@1 +cputln::@1: scope:[cputln] from cputln + to:cputln::@return +cputln::@return: scope:[cputln] from cputln::@1 + return + to:@return + +(void()) cscroll() +cscroll: scope:[cscroll] from cputln + (bool~) cscroll::$0 ← (byte) conio_cursor_y == (number) $19 + (bool~) cscroll::$1 ← ! (bool~) cscroll::$0 + if((bool~) cscroll::$1) goto cscroll::@return + to:cscroll::@1 +cscroll::@1: scope:[cscroll] from cscroll + (bool~) cscroll::$7 ← (number) 0 != (byte) conio_scroll_enable + if((bool~) cscroll::$7) goto cscroll::@3 + to:cscroll::@2 +cscroll::@3: scope:[cscroll] from cscroll::@1 + (void*) memcpy::destination#0 ← (void*)(const nomodify byte*) CONIO_SCREEN_TEXT + (void*) memcpy::source#0 ← (void*)(const nomodify byte*) CONIO_SCREEN_TEXT+(number) $50 + (word) memcpy::num#0 ← (number) $19*(number) $50-(number) $50 + call memcpy + (void*) memcpy::return#2 ← (void*) memcpy::return#1 + to:cscroll::@4 +cscroll::@4: scope:[cscroll] from cscroll::@3 + (void*) memcpy::destination#1 ← (void*)(const nomodify byte*) CONIO_SCREEN_COLORS + (void*) memcpy::source#1 ← (void*)(const nomodify byte*) CONIO_SCREEN_COLORS+(number) $50 + (word) memcpy::num#1 ← (number) $19*(number) $50-(number) $50 + call memcpy + (void*) memcpy::return#3 ← (void*) memcpy::return#1 + to:cscroll::@5 +cscroll::@5: scope:[cscroll] from cscroll::@4 + (void*) memset::str#0 ← (void*)(const nomodify byte*) CONIO_SCREEN_TEXT+(number) $19*(number) $50-(number) $50 + (byte) memset::c#0 ← (byte) ' ' + (word) memset::num#0 ← (number) $50 + call memset + (void*) memset::return#2 ← (void*) memset::return#1 + to:cscroll::@6 +cscroll::@6: scope:[cscroll] from cscroll::@5 + (void*) memset::str#1 ← (void*)(const nomodify byte*) CONIO_SCREEN_COLORS+(number) $19*(number) $50-(number) $50 + (byte) memset::c#1 ← (byte) conio_textcolor + (word) memset::num#1 ← (number) $50 + call memset + (void*) memset::return#3 ← (void*) memset::return#1 + to:cscroll::@7 +cscroll::@7: scope:[cscroll] from cscroll::@6 + (byte*) conio_line_text ← (byte*) conio_line_text - (number) $50 + (byte*) conio_line_color ← (byte*) conio_line_color - (number) $50 + (byte) conio_cursor_y ← -- (byte) conio_cursor_y + to:cscroll::@return +cscroll::@2: scope:[cscroll] from cscroll::@1 + (byte) gotoxy::x#1 ← (number) 0 + (byte) gotoxy::y#1 ← (number) 0 + call gotoxy + to:cscroll::@8 +cscroll::@8: scope:[cscroll] from cscroll::@2 + to:cscroll::@return +cscroll::@return: scope:[cscroll] from cscroll cscroll::@7 cscroll::@8 + return + to:@return + +(void()) cputs((to_nomodify byte*) cputs::s) +cputs: scope:[cputs] from main + (to_nomodify byte*) cputs::s#3 ← phi( main/(to_nomodify byte*) cputs::s#1 ) + (byte) cputs::c#0 ← (byte) 0 + to:cputs::@1 +cputs::@1: scope:[cputs] from cputs cputs::@3 + (to_nomodify byte*) cputs::s#2 ← phi( cputs/(to_nomodify byte*) cputs::s#3 cputs::@3/(to_nomodify byte*) cputs::s#4 ) + (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2) + (byte~) cputs::$0 ← (byte) cputs::c#1 + (to_nomodify byte*) cputs::s#0 ← ++ (to_nomodify byte*) cputs::s#2 + (bool~) cputs::$2 ← (number) 0 != (byte~) cputs::$0 + if((bool~) cputs::$2) goto cputs::@2 + to:cputs::@return +cputs::@2: scope:[cputs] from cputs::@1 + (to_nomodify byte*) cputs::s#5 ← phi( cputs::@1/(to_nomodify byte*) cputs::s#0 ) + (byte) cputs::c#2 ← phi( cputs::@1/(byte) cputs::c#1 ) + (byte) cputc::c#0 ← (byte) cputs::c#2 + call cputc + to:cputs::@3 +cputs::@3: scope:[cputs] from cputs::@2 + (to_nomodify byte*) cputs::s#4 ← phi( cputs::@2/(to_nomodify byte*) cputs::s#5 ) + to:cputs::@1 +cputs::@return: scope:[cputs] from cputs::@1 + return + to:@return + +(void()) conio_mega65_init() +conio_mega65_init: scope:[conio_mega65_init] from __start::__init1 + asm { sei } + asm { lda#0 tax tay taz map eom } + *((const nomodify to_volatile byte*) IO_KEY) ← (number) $47 + *((const nomodify to_volatile byte*) IO_KEY) ← (number) $53 + *((const nomodify to_volatile byte*) IO_BANK) ← *((const nomodify to_volatile byte*) IO_BANK) | (const nomodify byte) CRAM2K + to:conio_mega65_init::@return +conio_mega65_init::@return: scope:[conio_mega65_init] from conio_mega65_init + return + to:@return + +(void()) main() +main: scope:[main] from __start::@1 + (to_nomodify byte*) cputs::s#1 ← (const byte*) main::s + call cputs + to:main::@1 +main::@1: scope:[main] from main + to:main::@return +main::@return: scope:[main] from main::@1 + return + to:@return + +(void()) __start() +__start: scope:[__start] from + to:__start::__init1 +__start::__init1: scope:[__start] from __start + (byte) conio_cursor_x ← (byte) 0 + (byte) conio_cursor_y ← (byte) 0 + (byte*) conio_line_text ← (const nomodify byte*) CONIO_SCREEN_TEXT + (byte*) conio_line_color ← (const nomodify byte*) CONIO_SCREEN_COLORS + (byte) conio_textcolor ← (const nomodify byte) CONIO_TEXTCOLOR_DEFAULT + (byte) conio_scroll_enable ← (byte) 1 + call conio_mega65_init + to:__start::@2 +__start::@2: scope:[__start] from __start::__init1 + to:__start::@1 +__start::@1: scope:[__start] from __start::@2 + call main + to:__start::@3 +__start::@3: scope:[__start] from __start::@1 + to:__start::@return +__start::@return: scope:[__start] from __start::@3 + return + to:@return + +SYMBOL TABLE SSA +(const nomodify byte*) COLORRAM = (byte*)(number) $d800 +(const nomodify byte*) CONIO_SCREEN_COLORS = (const nomodify byte*) COLORRAM +(const nomodify byte*) CONIO_SCREEN_TEXT = (const nomodify byte*) DEFAULT_SCREEN +(const nomodify byte) CONIO_TEXTCOLOR_DEFAULT = (const nomodify byte) LIGHT_BLUE +(const nomodify byte) CRAM2K = (byte) 1 +(const nomodify byte*) DEFAULT_SCREEN = (byte*)(number) $800 +(const nomodify to_volatile byte*) IO_BANK = (byte*)(number) $d030 +(const nomodify to_volatile byte*) IO_KEY = (byte*)(number) $d02f +(const nomodify byte) LIGHT_BLUE = (byte) $e +(byte) MOS6526_CIA::INTERRUPT +(byte) MOS6526_CIA::PORT_A +(byte) MOS6526_CIA::PORT_A_DDR +(byte) MOS6526_CIA::PORT_B +(byte) MOS6526_CIA::PORT_B_DDR +(byte) MOS6526_CIA::SERIAL_DATA +(word) MOS6526_CIA::TIMER_A +(byte) MOS6526_CIA::TIMER_A_CONTROL +(word) MOS6526_CIA::TIMER_B +(byte) MOS6526_CIA::TIMER_B_CONTROL +(byte) MOS6526_CIA::TOD_10THS +(byte) MOS6526_CIA::TOD_HOURS +(byte) MOS6526_CIA::TOD_MIN +(byte) MOS6526_CIA::TOD_SEC +(byte) MOS6569_VICII::BG_COLOR +(byte) MOS6569_VICII::BG_COLOR1 +(byte) MOS6569_VICII::BG_COLOR2 +(byte) MOS6569_VICII::BG_COLOR3 +(byte) MOS6569_VICII::BORDER_COLOR +(byte) MOS6569_VICII::CONTROL1 +(byte) MOS6569_VICII::CONTROL2 +(byte) MOS6569_VICII::IRQ_ENABLE +(byte) MOS6569_VICII::IRQ_STATUS +(byte) MOS6569_VICII::LIGHTPEN_X +(byte) MOS6569_VICII::LIGHTPEN_Y +(byte) MOS6569_VICII::MEMORY +(byte) MOS6569_VICII::RASTER +(byte) MOS6569_VICII::SPRITE0_COLOR +(byte) MOS6569_VICII::SPRITE0_X +(byte) MOS6569_VICII::SPRITE0_Y +(byte) MOS6569_VICII::SPRITE1_COLOR +(byte) MOS6569_VICII::SPRITE1_X +(byte) MOS6569_VICII::SPRITE1_Y +(byte) MOS6569_VICII::SPRITE2_COLOR +(byte) MOS6569_VICII::SPRITE2_X +(byte) MOS6569_VICII::SPRITE2_Y +(byte) MOS6569_VICII::SPRITE3_COLOR +(byte) MOS6569_VICII::SPRITE3_X +(byte) MOS6569_VICII::SPRITE3_Y +(byte) MOS6569_VICII::SPRITE4_COLOR +(byte) MOS6569_VICII::SPRITE4_X +(byte) MOS6569_VICII::SPRITE4_Y +(byte) MOS6569_VICII::SPRITE5_COLOR +(byte) MOS6569_VICII::SPRITE5_X +(byte) MOS6569_VICII::SPRITE5_Y +(byte) MOS6569_VICII::SPRITE6_COLOR +(byte) MOS6569_VICII::SPRITE6_X +(byte) MOS6569_VICII::SPRITE6_Y +(byte) MOS6569_VICII::SPRITE7_COLOR +(byte) MOS6569_VICII::SPRITE7_X +(byte) MOS6569_VICII::SPRITE7_Y +(byte) MOS6569_VICII::SPRITES_BG_COLLISION +(byte) MOS6569_VICII::SPRITES_COLLISION +(byte) MOS6569_VICII::SPRITES_ENABLE +(byte) MOS6569_VICII::SPRITES_EXPAND_X +(byte) MOS6569_VICII::SPRITES_EXPAND_Y +(byte) MOS6569_VICII::SPRITES_MC +(byte) MOS6569_VICII::SPRITES_MCOLOR1 +(byte) MOS6569_VICII::SPRITES_MCOLOR2 +(byte) MOS6569_VICII::SPRITES_PRIORITY +(byte) MOS6569_VICII::SPRITES_XMSB +(byte) MOS6581_SID::CH1_ATTACK_DECAY +(byte) MOS6581_SID::CH1_CONTROL +(word) MOS6581_SID::CH1_FREQ +(word) MOS6581_SID::CH1_PULSE_WIDTH +(byte) MOS6581_SID::CH1_SUSTAIN_RELEASE +(byte) MOS6581_SID::CH2_ATTACK_DECAY +(byte) MOS6581_SID::CH2_CONTROL +(word) MOS6581_SID::CH2_FREQ +(word) MOS6581_SID::CH2_PULSE_WIDTH +(byte) MOS6581_SID::CH2_SUSTAIN_RELEASE +(byte) MOS6581_SID::CH3_ATTACK_DECAY +(byte) MOS6581_SID::CH3_CONTROL +(byte) MOS6581_SID::CH3_ENV +(word) MOS6581_SID::CH3_FREQ +(byte) MOS6581_SID::CH3_OSC +(word) MOS6581_SID::CH3_PULSE_WIDTH +(byte) MOS6581_SID::CH3_SUSTAIN_RELEASE +(byte) MOS6581_SID::FILTER_CUTOFF_HIGH +(byte) MOS6581_SID::FILTER_CUTOFF_LOW +(byte) MOS6581_SID::FILTER_SETUP +(byte) MOS6581_SID::POT_X +(byte) MOS6581_SID::POT_Y +(byte) MOS6581_SID::VOLUME_FILTER_MODE +(const byte) RADIX::BINARY = (number) 2 +(const byte) RADIX::DECIMAL = (number) $a +(const byte) RADIX::HEXADECIMAL = (number) $10 +(const byte) RADIX::OCTAL = (number) 8 +(void()) __start() +(label) __start::@1 +(label) __start::@2 +(label) __start::@3 +(label) __start::@return +(label) __start::__init1 +(byte) conio_cursor_x loadstore +(byte) conio_cursor_y loadstore +(byte*) conio_line_color loadstore +(byte*) conio_line_text loadstore +(void()) conio_mega65_init() +(label) conio_mega65_init::@return +(byte) conio_scroll_enable loadstore +(byte) conio_textcolor loadstore +(void()) cputc((byte) cputc::c) +(bool~) cputc::$0 +(bool~) cputc::$1 +(bool~) cputc::$2 +(label) cputc::@1 +(label) cputc::@2 +(label) cputc::@3 +(label) cputc::@4 +(label) cputc::@5 +(label) cputc::@return +(byte) cputc::c +(byte) cputc::c#0 +(byte) cputc::c#1 +(byte) cputc::c#2 +(void()) cputln() +(label) cputln::@1 +(label) cputln::@return +(void()) cputs((to_nomodify byte*) cputs::s) +(byte~) cputs::$0 +(bool~) cputs::$2 +(label) cputs::@1 +(label) cputs::@2 +(label) cputs::@3 +(label) cputs::@return +(byte) cputs::c +(byte) cputs::c#0 +(byte) cputs::c#1 +(byte) cputs::c#2 +(to_nomodify byte*) cputs::s +(to_nomodify byte*) cputs::s#0 +(to_nomodify byte*) cputs::s#1 +(to_nomodify byte*) cputs::s#2 +(to_nomodify byte*) cputs::s#3 +(to_nomodify byte*) cputs::s#4 +(to_nomodify byte*) cputs::s#5 +(void()) cscroll() +(bool~) cscroll::$0 +(bool~) cscroll::$1 +(bool~) cscroll::$7 +(label) cscroll::@1 +(label) cscroll::@2 +(label) cscroll::@3 +(label) cscroll::@4 +(label) cscroll::@5 +(label) cscroll::@6 +(label) cscroll::@7 +(label) cscroll::@8 +(label) cscroll::@return +(void()) gotoxy((byte) gotoxy::x , (byte) gotoxy::y) +(bool~) gotoxy::$0 +(bool~) gotoxy::$1 +(bool~) gotoxy::$2 +(bool~) gotoxy::$3 +(number~) gotoxy::$4 +(byte*~) gotoxy::$5 +(byte*~) gotoxy::$6 +(word~) gotoxy::$7 +(label) gotoxy::@1 +(label) gotoxy::@2 +(label) gotoxy::@3 +(label) gotoxy::@4 +(label) gotoxy::@return +(word) gotoxy::line_offset +(word) gotoxy::line_offset#0 +(byte) gotoxy::x +(byte) gotoxy::x#0 +(byte) gotoxy::x#1 +(byte) gotoxy::x#2 +(byte) gotoxy::x#3 +(byte) gotoxy::x#4 +(byte) gotoxy::x#5 +(byte) gotoxy::y +(byte) gotoxy::y#0 +(byte) gotoxy::y#1 +(byte) gotoxy::y#2 +(byte) gotoxy::y#3 +(byte) gotoxy::y#4 +(byte) gotoxy::y#5 +(void()) main() +(label) main::@1 +(label) main::@return +(const byte*) main::s[(byte) $d] = (byte*) "hello world!" +(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num) +(byte*~) memcpy::$0 +(bool~) memcpy::$1 +(byte*~) memcpy::$2 +(label) memcpy::@1 +(label) memcpy::@2 +(label) memcpy::@3 +(label) memcpy::@return +(void*) memcpy::destination +(void*) memcpy::destination#0 +(void*) memcpy::destination#1 +(void*) memcpy::destination#2 +(void*) memcpy::destination#3 +(void*) memcpy::destination#4 +(void*) memcpy::destination#5 +(byte*) memcpy::dst +(byte*) memcpy::dst#0 +(byte*) memcpy::dst#1 +(byte*) memcpy::dst#2 +(byte*) memcpy::dst#3 +(word) memcpy::num +(word) memcpy::num#0 +(word) memcpy::num#1 +(word) memcpy::num#2 +(void*) memcpy::return +(void*) memcpy::return#0 +(void*) memcpy::return#1 +(void*) memcpy::return#2 +(void*) memcpy::return#3 +(void*) memcpy::return#4 +(void*) memcpy::source +(void*) memcpy::source#0 +(void*) memcpy::source#1 +(void*) memcpy::source#2 +(byte*) memcpy::src +(byte*) memcpy::src#0 +(byte*) memcpy::src#1 +(byte*) memcpy::src#2 +(byte*) memcpy::src#3 +(byte*) memcpy::src_end +(byte*) memcpy::src_end#0 +(byte*) memcpy::src_end#1 +(byte*) memcpy::src_end#2 +(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num) +(bool~) memset::$0 +(bool~) memset::$1 +(byte*~) memset::$2 +(bool~) memset::$3 +(byte*~) memset::$4 +(label) memset::@1 +(label) memset::@2 +(label) memset::@3 +(label) memset::@4 +(label) memset::@return +(byte) memset::c +(byte) memset::c#0 +(byte) memset::c#1 +(byte) memset::c#2 +(byte) memset::c#3 +(byte) memset::c#4 +(byte) memset::c#5 +(byte*) memset::dst +(byte*) memset::dst#0 +(byte*) memset::dst#1 +(byte*) memset::dst#2 +(byte*) memset::dst#3 +(byte*) memset::end +(byte*) memset::end#0 +(byte*) memset::end#1 +(byte*) memset::end#2 +(word) memset::num +(word) memset::num#0 +(word) memset::num#1 +(word) memset::num#2 +(word) memset::num#3 +(void*) memset::return +(void*) memset::return#0 +(void*) memset::return#1 +(void*) memset::return#2 +(void*) memset::return#3 +(void*) memset::return#4 +(void*) memset::str +(void*) memset::str#0 +(void*) memset::str#1 +(void*) memset::str#2 +(void*) memset::str#3 +(void*) memset::str#4 +(void*) memset::str#5 +(void*) memset::str#6 +(const byte*) printf_buffer_number::digits[(number) $b] = { fill( $b, 0) } +(byte) printf_buffer_number::sign +(byte) printf_format_number::justify_left +(byte) printf_format_number::min_length +(byte) printf_format_number::radix +(byte) printf_format_number::sign_always +(byte) printf_format_number::upper_case +(byte) printf_format_number::zero_padding +(byte) printf_format_string::justify_left +(byte) printf_format_string::min_length + +Adding number conversion cast (unumber) 0 in (bool~) memset::$0 ← (word) memset::num#2 > (number) 0 +Adding number conversion cast (unumber) $19 in (bool~) gotoxy::$0 ← (byte) gotoxy::y#2 > (number) $19 +Adding number conversion cast (unumber) $50 in (bool~) gotoxy::$2 ← (byte) gotoxy::x#2 >= (number) $50 +Adding number conversion cast (unumber) 0 in (byte) gotoxy::y#0 ← (number) 0 +Adding number conversion cast (unumber) $50 in (number~) gotoxy::$4 ← (word~) gotoxy::$7 * (number) $50 +Adding number conversion cast (unumber) gotoxy::$4 in (number~) gotoxy::$4 ← (word~) gotoxy::$7 * (unumber)(number) $50 +Adding number conversion cast (unumber) 0 in (byte) gotoxy::x#0 ← (number) 0 +Adding number conversion cast (unumber) $50 in (bool~) cputc::$1 ← (byte) conio_cursor_x == (number) $50 +Adding number conversion cast (unumber) $50 in (byte*) conio_line_text ← (byte*) conio_line_text + (number) $50 +Adding number conversion cast (unumber) $50 in (byte*) conio_line_color ← (byte*) conio_line_color + (number) $50 +Adding number conversion cast (unumber) 0 in (byte) conio_cursor_x ← (number) 0 +Adding number conversion cast (unumber) $19 in (bool~) cscroll::$0 ← (byte) conio_cursor_y == (number) $19 +Adding number conversion cast (unumber) 0 in (bool~) cscroll::$7 ← (number) 0 != (byte) conio_scroll_enable +Adding number conversion cast (unumber) $50 in (void*) memcpy::source#0 ← (void*)(const nomodify byte*) CONIO_SCREEN_TEXT+(number) $50 +Adding number conversion cast (unumber) $19*$50-$50 in (word) memcpy::num#0 ← (number) $19*(number) $50-(number) $50 +Adding number conversion cast (unumber) $50 in (void*) memcpy::source#1 ← (void*)(const nomodify byte*) CONIO_SCREEN_COLORS+(number) $50 +Adding number conversion cast (unumber) $19*$50-$50 in (word) memcpy::num#1 ← (number) $19*(number) $50-(number) $50 +Adding number conversion cast (unumber) $50 in (void*) memset::str#0 ← (void*)(const nomodify byte*) CONIO_SCREEN_TEXT+(number) $19*(number) $50-(number) $50 +Adding number conversion cast (unumber) $19*$50 in (void*) memset::str#0 ← (void*)(const nomodify byte*) CONIO_SCREEN_TEXT+(number) $19*(number) $50-(unumber)(number) $50 +Adding number conversion cast (unumber) $50 in (word) memset::num#0 ← (number) $50 +Adding number conversion cast (unumber) $50 in (void*) memset::str#1 ← (void*)(const nomodify byte*) CONIO_SCREEN_COLORS+(number) $19*(number) $50-(number) $50 +Adding number conversion cast (unumber) $19*$50 in (void*) memset::str#1 ← (void*)(const nomodify byte*) CONIO_SCREEN_COLORS+(number) $19*(number) $50-(unumber)(number) $50 +Adding number conversion cast (unumber) $50 in (word) memset::num#1 ← (number) $50 +Adding number conversion cast (unumber) $50 in (byte*) conio_line_text ← (byte*) conio_line_text - (number) $50 +Adding number conversion cast (unumber) $50 in (byte*) conio_line_color ← (byte*) conio_line_color - (number) $50 +Adding number conversion cast (unumber) 0 in (byte) gotoxy::x#1 ← (number) 0 +Adding number conversion cast (unumber) 0 in (byte) gotoxy::y#1 ← (number) 0 +Adding number conversion cast (unumber) 0 in (bool~) cputs::$2 ← (number) 0 != (byte~) cputs::$0 +Adding number conversion cast (unumber) $47 in *((const nomodify to_volatile byte*) IO_KEY) ← (number) $47 +Adding number conversion cast (unumber) $53 in *((const nomodify to_volatile byte*) IO_KEY) ← (number) $53 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast (byte*) memcpy::src#0 ← (byte*)(void*) memcpy::source#2 +Inlining cast (byte*) memcpy::dst#0 ← (byte*)(void*) memcpy::destination#2 +Inlining cast (byte*) memset::dst#0 ← (byte*)(void*) memset::str#3 +Inlining cast (byte) gotoxy::y#0 ← (unumber)(number) 0 +Inlining cast (byte) gotoxy::x#0 ← (unumber)(number) 0 +Inlining cast (byte) conio_cursor_x ← (unumber)(number) 0 +Inlining cast (word) memcpy::num#0 ← (unumber)(number) $19*(number) $50-(number) $50 +Inlining cast (word) memcpy::num#1 ← (unumber)(number) $19*(number) $50-(number) $50 +Inlining cast (word) memset::num#0 ← (unumber)(number) $50 +Inlining cast (word) memset::num#1 ← (unumber)(number) $50 +Inlining cast (byte) gotoxy::x#1 ← (unumber)(number) 0 +Inlining cast (byte) gotoxy::y#1 ← (unumber)(number) 0 +Inlining cast *((const nomodify to_volatile byte*) IO_KEY) ← (unumber)(number) $47 +Inlining cast *((const nomodify to_volatile byte*) IO_KEY) ← (unumber)(number) $53 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 53295 +Simplifying constant pointer cast (byte*) 53296 +Simplifying constant pointer cast (byte*) 55296 +Simplifying constant pointer cast (byte*) 2048 +Simplifying constant integer cast 0 +Simplifying constant integer cast $19 +Simplifying constant integer cast $50 +Simplifying constant integer cast 0 +Simplifying constant integer cast $50 +Simplifying constant integer cast 0 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast 0 +Simplifying constant integer cast $19 +Simplifying constant integer cast 0 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast $50 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast $47 +Simplifying constant integer cast $53 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $19 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $19 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) $50 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $47 +Finalized unsigned number type (byte) $53 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inferred type updated to word in (unumber~) gotoxy::$4 ← (word~) gotoxy::$7 * (byte) $50 +Inversing boolean not [20] (bool~) memset::$1 ← (word) memset::num#2 <= (byte) 0 from [19] (bool~) memset::$0 ← (word) memset::num#2 > (byte) 0 +Inversing boolean not [40] (bool~) gotoxy::$1 ← (byte) gotoxy::y#2 <= (byte) $19 from [39] (bool~) gotoxy::$0 ← (byte) gotoxy::y#2 > (byte) $19 +Inversing boolean not [44] (bool~) gotoxy::$3 ← (byte) gotoxy::x#2 < (byte) $50 from [43] (bool~) gotoxy::$2 ← (byte) gotoxy::x#2 >= (byte) $50 +Inversing boolean not [70] (bool~) cputc::$2 ← (byte) conio_cursor_x != (byte) $50 from [69] (bool~) cputc::$1 ← (byte) conio_cursor_x == (byte) $50 +Inversing boolean not [81] (bool~) cscroll::$1 ← (byte) conio_cursor_y != (byte) $19 from [80] (bool~) cscroll::$0 ← (byte) conio_cursor_y == (byte) $19 +Successful SSA optimization Pass2UnaryNotSimplification +Alias candidate removed (volatile)conio_line_text = gotoxy::$5 +Alias candidate removed (volatile)conio_line_color = gotoxy::$6 +Alias memcpy::src_end#0 = memcpy::$0 +Alias memcpy::src#2 = memcpy::src#3 +Alias memcpy::dst#2 = memcpy::dst#3 +Alias memcpy::src_end#1 = memcpy::src_end#2 +Alias memcpy::destination#3 = memcpy::destination#5 memcpy::destination#4 memcpy::return#0 memcpy::return#4 memcpy::return#1 +Alias memset::return#0 = memset::str#2 memset::return#4 memset::return#1 +Alias memset::str#3 = memset::str#4 +Alias memset::num#2 = memset::num#3 +Alias memset::c#4 = memset::c#5 +Alias memset::end#0 = memset::$2 +Alias memset::c#2 = memset::c#3 +Alias memset::dst#2 = memset::dst#3 +Alias memset::end#1 = memset::end#2 +Alias memset::str#5 = memset::str#6 +Alias gotoxy::x#4 = gotoxy::x#5 +Alias gotoxy::line_offset#0 = gotoxy::$4 +Alias gotoxy::y#4 = gotoxy::y#5 +Alias cputc::c#1 = cputc::c#2 +Alias cputs::c#1 = cputs::$0 cputs::c#2 +Alias cputs::s#0 = cputs::s#5 cputs::s#4 +Successful SSA optimization Pass2AliasElimination +Alias candidate removed (volatile)conio_line_text = gotoxy::$5 +Alias candidate removed (volatile)conio_line_color = gotoxy::$6 +Alias gotoxy::x#2 = gotoxy::x#4 +Alias gotoxy::y#3 = gotoxy::y#4 +Successful SSA optimization Pass2AliasElimination +Alias candidate removed (volatile)conio_line_text = gotoxy::$5 +Alias candidate removed (volatile)conio_line_color = gotoxy::$6 +Identical Phi Values (byte*) memcpy::src_end#1 (byte*) memcpy::src_end#0 +Identical Phi Values (void*) memcpy::destination#3 (void*) memcpy::destination#2 +Identical Phi Values (byte*) memset::end#1 (byte*) memset::end#0 +Identical Phi Values (void*) memset::str#5 (void*) memset::str#3 +Identical Phi Values (byte) memset::c#2 (byte) memset::c#4 +Identical Phi Values (byte) gotoxy::y#2 (byte) gotoxy::y#1 +Identical Phi Values (byte) gotoxy::x#2 (byte) gotoxy::x#1 +Identical Phi Values (byte) cputc::c#1 (byte) cputc::c#0 +Identical Phi Values (to_nomodify byte*) cputs::s#3 (to_nomodify byte*) cputs::s#1 +Successful SSA optimization Pass2IdenticalPhiElimination +Identical Phi Values (void*) memset::return#0 (void*) memset::str#3 +Successful SSA optimization Pass2IdenticalPhiElimination +Simple Condition (bool~) memcpy::$1 [7] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 +Simple Condition (bool~) memset::$1 [14] if((word) memset::num#2<=(byte) 0) goto memset::@1 +Simple Condition (bool~) memset::$3 [21] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@4 +Simple Condition (bool~) gotoxy::$1 [27] if((byte) gotoxy::y#1<=(byte) $19) goto gotoxy::@1 +Simple Condition (bool~) gotoxy::$3 [30] if((byte) gotoxy::x#1<(byte) $50) goto gotoxy::@2 +Simple Condition (bool~) cputc::$0 [45] if((byte) cputc::c#0==(byte) ' +') goto cputc::@1 +Simple Condition (bool~) cputc::$2 [51] if((byte) conio_cursor_x!=(byte) $50) goto cputc::@return +Simple Condition (bool~) cscroll::$1 [61] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return +Simple Condition (bool~) cscroll::$7 [63] if((byte) 0!=(byte) conio_scroll_enable) goto cscroll::@3 +Simple Condition (bool~) cputs::$2 [97] if((byte) 0!=(byte) cputs::c#1) goto cputs::@2 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant right-side identified [66] (word) memcpy::num#0 ← (unumber)(number) $19*(number) $50-(number) $50 +Constant right-side identified [71] (word) memcpy::num#1 ← (unumber)(number) $19*(number) $50-(number) $50 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) gotoxy::y#0 = 0 +Constant (const byte) gotoxy::x#0 = 0 +Constant (const void*) memcpy::destination#0 = (void*)CONIO_SCREEN_TEXT +Constant (const void*) memcpy::source#0 = (void*)CONIO_SCREEN_TEXT+$50 +Constant (const word) memcpy::num#0 = (unumber)$19*$50-$50 +Constant (const void*) memcpy::destination#1 = (void*)CONIO_SCREEN_COLORS +Constant (const void*) memcpy::source#1 = (void*)CONIO_SCREEN_COLORS+$50 +Constant (const word) memcpy::num#1 = (unumber)$19*$50-$50 +Constant (const void*) memset::str#0 = (void*)CONIO_SCREEN_TEXT+(word)$19*$50-$50 +Constant (const byte) memset::c#0 = ' ' +Constant (const word) memset::num#0 = $50 +Constant (const void*) memset::str#1 = (void*)CONIO_SCREEN_COLORS+(word)$19*$50-$50 +Constant (const word) memset::num#1 = $50 +Constant (const byte) gotoxy::x#1 = 0 +Constant (const byte) gotoxy::y#1 = 0 +Constant (const byte) cputs::c#0 = 0 +Constant (const to_nomodify byte*) cputs::s#1 = main::s +Constant (const byte) conio_textcolor = CONIO_TEXTCOLOR_DEFAULT +Constant (const byte) conio_scroll_enable = 1 +Successful SSA optimization Pass2ConstantIdentification +Constant (const byte) memset::c#1 = conio_textcolor +Successful SSA optimization Pass2ConstantIdentification +if() condition always true - replacing block destination [27] if((const byte) gotoxy::y#1<=(byte) $19) goto gotoxy::@1 +if() condition always true - replacing block destination [30] if((const byte) gotoxy::x#1<(byte) $50) goto gotoxy::@2 +if() condition always true - replacing block destination [63] if((byte) 0!=(const byte) conio_scroll_enable) goto cscroll::@3 +Successful SSA optimization Pass2ConstantIfs +Eliminating unused variable (void*) memcpy::return#2 and assignment [48] (void*) memcpy::return#2 ← (void*) memcpy::destination#2 +Eliminating unused variable (void*) memcpy::return#3 and assignment [50] (void*) memcpy::return#3 ← (void*) memcpy::destination#2 +Eliminating unused variable (void*) memset::return#2 and assignment [52] (void*) memset::return#2 ← (void*) memset::str#3 +Eliminating unused variable (void*) memset::return#3 and assignment [54] (void*) memset::return#3 ← (void*) memset::str#3 +Eliminating unused constant (const byte) cputs::c#0 +Eliminating unused constant (const byte) conio_scroll_enable +Successful SSA optimization PassNEliminateUnusedVars +Eliminating variable (byte) gotoxy::y#3 from unused block gotoxy::@1 +Eliminating variable (byte) gotoxy::x#3 from unused block gotoxy::@2 +Eliminating variable (word~) gotoxy::$7 from unused block gotoxy::@2 +Eliminating variable (word) gotoxy::line_offset#0 from unused block gotoxy::@2 +Eliminating variable (byte*~) gotoxy::$5 from unused block gotoxy::@2 +Eliminating variable (byte*~) gotoxy::$6 from unused block gotoxy::@2 +Removing unused procedure gotoxy +Removing unused procedure block gotoxy +Removing PHI-reference to removed block (gotoxy) in block gotoxy::@1 +Removing unused procedure block gotoxy::@1 +Removing PHI-reference to removed block (gotoxy::@1) in block gotoxy::@2 +Removing unused procedure block gotoxy::@3 +Removing unused procedure block gotoxy::@2 +Removing unused procedure block gotoxy::@4 +Removing unused procedure block gotoxy::@return +Removing unused block cscroll::@2 +Removing unused block cscroll::@8 +Successful SSA optimization Pass2EliminateUnusedBlocks +Inlining Noop Cast [1] (byte*) memcpy::src#0 ← (byte*)(void*) memcpy::source#2 keeping memcpy::source#2 +Inlining Noop Cast [2] (byte*) memcpy::dst#0 ← (byte*)(void*) memcpy::destination#2 keeping memcpy::destination#2 +Inlining Noop Cast [3] (byte*~) memcpy::$2 ← (byte*)(void*) memcpy::source#2 keeping memcpy::source#2 +Inlining Noop Cast [13] (byte*~) memset::$4 ← (byte*)(void*) memset::str#3 keeping memset::str#3 +Inlining Noop Cast [15] (byte*) memset::dst#0 ← (byte*)(void*) memset::str#3 keeping memset::str#3 +Successful SSA optimization Pass2NopCastInlining +Inlining constant with var siblings (const void*) memcpy::destination#0 +Inlining constant with var siblings (const void*) memcpy::source#0 +Inlining constant with var siblings (const word) memcpy::num#0 +Inlining constant with var siblings (const void*) memcpy::destination#1 +Inlining constant with var siblings (const void*) memcpy::source#1 +Inlining constant with var siblings (const word) memcpy::num#1 +Inlining constant with var siblings (const void*) memset::str#0 +Inlining constant with var siblings (const byte) memset::c#0 +Inlining constant with var siblings (const word) memset::num#0 +Inlining constant with var siblings (const void*) memset::str#1 +Inlining constant with var siblings (const word) memset::num#1 +Inlining constant with var siblings (const byte) memset::c#1 +Inlining constant with var siblings (const to_nomodify byte*) cputs::s#1 +Constant inlined memset::str#1 = (void*)(const nomodify byte*) COLORRAM+(word)(number) $19*(number) $50-(byte) $50 +Constant inlined memset::str#0 = (void*)(const nomodify byte*) DEFAULT_SCREEN+(word)(number) $19*(number) $50-(byte) $50 +Constant inlined CONIO_SCREEN_COLORS = (const nomodify byte*) COLORRAM +Constant inlined cputs::s#1 = (const byte*) main::s +Constant inlined conio_textcolor = (const nomodify byte) LIGHT_BLUE +Constant inlined memcpy::destination#0 = (void*)(const nomodify byte*) DEFAULT_SCREEN +Constant inlined memset::num#1 = (byte) $50 +Constant inlined memcpy::destination#1 = (void*)(const nomodify byte*) COLORRAM +Constant inlined memset::num#0 = (byte) $50 +Constant inlined memcpy::source#0 = (void*)(const nomodify byte*) DEFAULT_SCREEN+(byte) $50 +Constant inlined memcpy::num#1 = (word)(number) $19*(number) $50-(number) $50 +Constant inlined memcpy::num#0 = (word)(number) $19*(number) $50-(number) $50 +Constant inlined memcpy::source#1 = (void*)(const nomodify byte*) COLORRAM+(byte) $50 +Constant inlined CONIO_SCREEN_TEXT = (const nomodify byte*) DEFAULT_SCREEN +Constant inlined memset::c#0 = (byte) ' ' +Constant inlined memset::c#1 = (const nomodify byte) LIGHT_BLUE +Constant inlined CONIO_TEXTCOLOR_DEFAULT = (const nomodify byte) LIGHT_BLUE +Successful SSA optimization Pass2ConstantInlining +Identical Phi Values (word) memcpy::num#2 (word)(number) $19*(number) $50-(number) $50 +Identical Phi Values (word) memset::num#2 (byte) $50 +Successful SSA optimization Pass2IdenticalPhiElimination +if() condition always false - eliminating [9] if((byte) $50<=(byte) 0) goto memset::@1 +Successful SSA optimization Pass2ConstantIfs +Adding NOP phi() at start of __start +Adding NOP phi() at start of __start::@2 +Adding NOP phi() at start of __start::@1 +Adding NOP phi() at start of __start::@3 +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 +Adding NOP phi() at start of cputs +Adding NOP phi() at start of cputc::@3 +Adding NOP phi() at start of cputc::@5 +Adding NOP phi() at start of cputc::@1 +Adding NOP phi() at start of cputc::@4 +Adding NOP phi() at start of cputln::@1 +Adding NOP phi() at start of cscroll::@1 +Adding NOP phi() at start of cscroll::@3 +Adding NOP phi() at start of cscroll::@4 +Adding NOP phi() at start of cscroll::@5 +Adding NOP phi() at start of cscroll::@6 +Adding NOP phi() at start of memcpy::@3 +Adding NOP phi() at start of memset::@1 +CALL GRAPH +Calls in [__start] to conio_mega65_init:5 main:8 +Calls in [main] to cputs:18 +Calls in [cputs] to cputc:28 +Calls in [cputc] to cputln:36 cputln:40 +Calls in [cputln] to cscroll:46 +Calls in [cscroll] to memcpy:52 memcpy:54 memset:56 memset:58 + +Created 8 initial phi equivalence classes +Coalesced [29] cputs::s#6 ← cputs::s#0 +Coalesced [74] memcpy::src#5 ← memcpy::src#1 +Coalesced [75] memcpy::dst#5 ← memcpy::dst#1 +Coalesced [85] memset::dst#5 ← memset::dst#1 +Coalesced down to 8 phi equivalence classes +Culled Empty Block (label) __start::@2 +Culled Empty Block (label) __start::@3 +Culled Empty Block (label) main::@1 +Culled Empty Block (label) cputs::@3 +Culled Empty Block (label) cputc::@5 +Culled Empty Block (label) cputc::@4 +Culled Empty Block (label) cputln::@1 +Culled Empty Block (label) cscroll::@1 +Culled Empty Block (label) memcpy::@3 +Culled Empty Block (label) memset::@1 +Renumbering block memset::@2 to memset::@1 +Renumbering block memset::@3 to memset::@2 +Renumbering block memset::@4 to memset::@3 +Renumbering block cscroll::@3 to cscroll::@1 +Renumbering block cscroll::@4 to cscroll::@2 +Renumbering block cscroll::@5 to cscroll::@3 +Renumbering block cscroll::@6 to cscroll::@4 +Renumbering block cscroll::@7 to cscroll::@5 +Adding NOP phi() at start of __start +Adding NOP phi() at start of __start::@1 +Adding NOP phi() at start of main +Adding NOP phi() at start of cputs +Adding NOP phi() at start of cputc::@3 +Adding NOP phi() at start of cputc::@1 +Adding NOP phi() at start of cscroll::@1 +Adding NOP phi() at start of cscroll::@2 +Adding NOP phi() at start of cscroll::@3 +Adding NOP phi() at start of cscroll::@4 + +FINAL CONTROL FLOW GRAPH + +(void()) __start() +__start: scope:[__start] from + [0] phi() + to:__start::__init1 +__start::__init1: scope:[__start] from __start + [1] (byte) conio_cursor_x ← (byte) 0 + [2] (byte) conio_cursor_y ← (byte) 0 + [3] (byte*) conio_line_text ← (const nomodify byte*) DEFAULT_SCREEN + [4] (byte*) conio_line_color ← (const nomodify byte*) COLORRAM + [5] call conio_mega65_init + to:__start::@1 +__start::@1: scope:[__start] from __start::__init1 + [6] phi() + [7] call main + to:__start::@return +__start::@return: scope:[__start] from __start::@1 + [8] return + to:@return + +(void()) conio_mega65_init() +conio_mega65_init: scope:[conio_mega65_init] from __start::__init1 + asm { sei } + asm { lda#0 tax tay taz map eom } + [11] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $47 + [12] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $53 + [13] *((const nomodify to_volatile byte*) IO_BANK) ← *((const nomodify to_volatile byte*) IO_BANK) | (const nomodify byte) CRAM2K + to:conio_mega65_init::@return +conio_mega65_init::@return: scope:[conio_mega65_init] from conio_mega65_init + [14] return + to:@return + +(void()) main() +main: scope:[main] from __start::@1 + [15] phi() + [16] call cputs + to:main::@return +main::@return: scope:[main] from main + [17] return + to:@return + +(void()) cputs((to_nomodify byte*) cputs::s) +cputs: scope:[cputs] from main + [18] phi() + to:cputs::@1 +cputs::@1: scope:[cputs] from cputs cputs::@2 + [19] (to_nomodify byte*) cputs::s#2 ← phi( cputs/(const byte*) main::s cputs::@2/(to_nomodify byte*) cputs::s#0 ) + [20] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2) + [21] (to_nomodify byte*) cputs::s#0 ← ++ (to_nomodify byte*) cputs::s#2 + [22] if((byte) 0!=(byte) cputs::c#1) goto cputs::@2 + to:cputs::@return +cputs::@return: scope:[cputs] from cputs::@1 + [23] return + to:@return +cputs::@2: scope:[cputs] from cputs::@1 + [24] (byte) cputc::c#0 ← (byte) cputs::c#1 + [25] call cputc + to:cputs::@1 + +(void()) cputc((byte) cputc::c) +cputc: scope:[cputc] from cputs::@2 + [26] if((byte) cputc::c#0==(byte) ' +') goto cputc::@1 + to:cputc::@2 +cputc::@2: scope:[cputc] from cputc + [27] *((byte*) conio_line_text + (byte) conio_cursor_x) ← (byte) cputc::c#0 + [28] *((byte*) conio_line_color + (byte) conio_cursor_x) ← (const nomodify byte) LIGHT_BLUE + [29] (byte) conio_cursor_x ← ++ (byte) conio_cursor_x + [30] if((byte) conio_cursor_x!=(byte) $50) goto cputc::@return + to:cputc::@3 +cputc::@3: scope:[cputc] from cputc::@2 + [31] phi() + [32] call cputln + to:cputc::@return +cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@3 + [33] return + to:@return +cputc::@1: scope:[cputc] from cputc + [34] phi() + [35] call cputln + to:cputc::@return + +(void()) cputln() +cputln: scope:[cputln] from cputc::@1 cputc::@3 + [36] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $50 + [37] (byte*) conio_line_color ← (byte*) conio_line_color + (byte) $50 + [38] (byte) conio_cursor_x ← (byte) 0 + [39] (byte) conio_cursor_y ← ++ (byte) conio_cursor_y + [40] call cscroll + to:cputln::@return +cputln::@return: scope:[cputln] from cputln + [41] return + to:@return + +(void()) cscroll() +cscroll: scope:[cscroll] from cputln + [42] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return + to:cscroll::@1 +cscroll::@1: scope:[cscroll] from cscroll + [43] phi() + [44] call memcpy + to:cscroll::@2 +cscroll::@2: scope:[cscroll] from cscroll::@1 + [45] phi() + [46] call memcpy + to:cscroll::@3 +cscroll::@3: scope:[cscroll] from cscroll::@2 + [47] phi() + [48] call memset + to:cscroll::@4 +cscroll::@4: scope:[cscroll] from cscroll::@3 + [49] phi() + [50] call memset + to:cscroll::@5 +cscroll::@5: scope:[cscroll] from cscroll::@4 + [51] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $50 + [52] (byte*) conio_line_color ← (byte*) conio_line_color - (byte) $50 + [53] (byte) conio_cursor_y ← -- (byte) conio_cursor_y + to:cscroll::@return +cscroll::@return: scope:[cscroll] from cscroll cscroll::@5 + [54] return + to:@return + +(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num) +memcpy: scope:[memcpy] from cscroll::@1 cscroll::@2 + [55] (void*) memcpy::destination#2 ← phi( cscroll::@1/(void*)(const nomodify byte*) DEFAULT_SCREEN cscroll::@2/(void*)(const nomodify byte*) COLORRAM ) + [55] (void*) memcpy::source#2 ← phi( cscroll::@1/(void*)(const nomodify byte*) DEFAULT_SCREEN+(byte) $50 cscroll::@2/(void*)(const nomodify byte*) COLORRAM+(byte) $50 ) + [56] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word)(number) $19*(number) $50-(number) $50 + [57] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 + [58] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 + to:memcpy::@1 +memcpy::@1: scope:[memcpy] from memcpy memcpy::@2 + [59] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#4 memcpy::@2/(byte*) memcpy::dst#1 ) + [59] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#4 memcpy::@2/(byte*) memcpy::src#1 ) + [60] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 + to:memcpy::@return +memcpy::@return: scope:[memcpy] from memcpy::@1 + [61] return + to:@return +memcpy::@2: scope:[memcpy] from memcpy::@1 + [62] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) + [63] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 + [64] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 + to:memcpy::@1 + +(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num) +memset: scope:[memset] from cscroll::@3 cscroll::@4 + [65] (byte) memset::c#4 ← phi( cscroll::@3/(byte) ' ' cscroll::@4/(const nomodify byte) LIGHT_BLUE ) + [65] (void*) memset::str#3 ← phi( cscroll::@3/(void*)(const nomodify byte*) DEFAULT_SCREEN+(word)(number) $19*(number) $50-(byte) $50 cscroll::@4/(void*)(const nomodify byte*) COLORRAM+(word)(number) $19*(number) $50-(byte) $50 ) + to:memset::@1 +memset::@1: scope:[memset] from memset + [66] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (byte) $50 + [67] (byte*) memset::dst#4 ← (byte*)(void*) memset::str#3 + to:memset::@2 +memset::@2: scope:[memset] from memset::@1 memset::@3 + [68] (byte*) memset::dst#2 ← phi( memset::@1/(byte*) memset::dst#4 memset::@3/(byte*) memset::dst#1 ) + [69] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3 + to:memset::@return +memset::@return: scope:[memset] from memset::@2 + [70] return + to:@return +memset::@3: scope:[memset] from memset::@2 + [71] *((byte*) memset::dst#2) ← (byte) memset::c#4 + [72] (byte*) memset::dst#1 ← ++ (byte*) memset::dst#2 + to:memset::@2 + + +VARIABLE REGISTER WEIGHTS +(byte) MOS6526_CIA::INTERRUPT +(byte) MOS6526_CIA::PORT_A +(byte) MOS6526_CIA::PORT_A_DDR +(byte) MOS6526_CIA::PORT_B +(byte) MOS6526_CIA::PORT_B_DDR +(byte) MOS6526_CIA::SERIAL_DATA +(word) MOS6526_CIA::TIMER_A +(byte) MOS6526_CIA::TIMER_A_CONTROL +(word) MOS6526_CIA::TIMER_B +(byte) MOS6526_CIA::TIMER_B_CONTROL +(byte) MOS6526_CIA::TOD_10THS +(byte) MOS6526_CIA::TOD_HOURS +(byte) MOS6526_CIA::TOD_MIN +(byte) MOS6526_CIA::TOD_SEC +(byte) MOS6569_VICII::BG_COLOR +(byte) MOS6569_VICII::BG_COLOR1 +(byte) MOS6569_VICII::BG_COLOR2 +(byte) MOS6569_VICII::BG_COLOR3 +(byte) MOS6569_VICII::BORDER_COLOR +(byte) MOS6569_VICII::CONTROL1 +(byte) MOS6569_VICII::CONTROL2 +(byte) MOS6569_VICII::IRQ_ENABLE +(byte) MOS6569_VICII::IRQ_STATUS +(byte) MOS6569_VICII::LIGHTPEN_X +(byte) MOS6569_VICII::LIGHTPEN_Y +(byte) MOS6569_VICII::MEMORY +(byte) MOS6569_VICII::RASTER +(byte) MOS6569_VICII::SPRITE0_COLOR +(byte) MOS6569_VICII::SPRITE0_X +(byte) MOS6569_VICII::SPRITE0_Y +(byte) MOS6569_VICII::SPRITE1_COLOR +(byte) MOS6569_VICII::SPRITE1_X +(byte) MOS6569_VICII::SPRITE1_Y +(byte) MOS6569_VICII::SPRITE2_COLOR +(byte) MOS6569_VICII::SPRITE2_X +(byte) MOS6569_VICII::SPRITE2_Y +(byte) MOS6569_VICII::SPRITE3_COLOR +(byte) MOS6569_VICII::SPRITE3_X +(byte) MOS6569_VICII::SPRITE3_Y +(byte) MOS6569_VICII::SPRITE4_COLOR +(byte) MOS6569_VICII::SPRITE4_X +(byte) MOS6569_VICII::SPRITE4_Y +(byte) MOS6569_VICII::SPRITE5_COLOR +(byte) MOS6569_VICII::SPRITE5_X +(byte) MOS6569_VICII::SPRITE5_Y +(byte) MOS6569_VICII::SPRITE6_COLOR +(byte) MOS6569_VICII::SPRITE6_X +(byte) MOS6569_VICII::SPRITE6_Y +(byte) MOS6569_VICII::SPRITE7_COLOR +(byte) MOS6569_VICII::SPRITE7_X +(byte) MOS6569_VICII::SPRITE7_Y +(byte) MOS6569_VICII::SPRITES_BG_COLLISION +(byte) MOS6569_VICII::SPRITES_COLLISION +(byte) MOS6569_VICII::SPRITES_ENABLE +(byte) MOS6569_VICII::SPRITES_EXPAND_X +(byte) MOS6569_VICII::SPRITES_EXPAND_Y +(byte) MOS6569_VICII::SPRITES_MC +(byte) MOS6569_VICII::SPRITES_MCOLOR1 +(byte) MOS6569_VICII::SPRITES_MCOLOR2 +(byte) MOS6569_VICII::SPRITES_PRIORITY +(byte) MOS6569_VICII::SPRITES_XMSB +(byte) MOS6581_SID::CH1_ATTACK_DECAY +(byte) MOS6581_SID::CH1_CONTROL +(word) MOS6581_SID::CH1_FREQ +(word) MOS6581_SID::CH1_PULSE_WIDTH +(byte) MOS6581_SID::CH1_SUSTAIN_RELEASE +(byte) MOS6581_SID::CH2_ATTACK_DECAY +(byte) MOS6581_SID::CH2_CONTROL +(word) MOS6581_SID::CH2_FREQ +(word) MOS6581_SID::CH2_PULSE_WIDTH +(byte) MOS6581_SID::CH2_SUSTAIN_RELEASE +(byte) MOS6581_SID::CH3_ATTACK_DECAY +(byte) MOS6581_SID::CH3_CONTROL +(byte) MOS6581_SID::CH3_ENV +(word) MOS6581_SID::CH3_FREQ +(byte) MOS6581_SID::CH3_OSC +(word) MOS6581_SID::CH3_PULSE_WIDTH +(byte) MOS6581_SID::CH3_SUSTAIN_RELEASE +(byte) MOS6581_SID::FILTER_CUTOFF_HIGH +(byte) MOS6581_SID::FILTER_CUTOFF_LOW +(byte) MOS6581_SID::FILTER_SETUP +(byte) MOS6581_SID::POT_X +(byte) MOS6581_SID::POT_Y +(byte) MOS6581_SID::VOLUME_FILTER_MODE +(void()) __start() +(byte) conio_cursor_x loadstore 5769.538461538461 +(byte) conio_cursor_y loadstore 76190.64285714286 +(byte*) conio_line_color loadstore 55250.175 +(byte*) conio_line_text loadstore 53902.60975609756 +(void()) conio_mega65_init() +(void()) cputc((byte) cputc::c) +(byte) cputc::c +(byte) cputc::c#0 10501.5 +(void()) cputln() +(void()) cputs((to_nomodify byte*) cputs::s) +(byte) cputs::c +(byte) cputs::c#1 1001.0 +(to_nomodify byte*) cputs::s +(to_nomodify byte*) cputs::s#0 500.5 +(to_nomodify byte*) cputs::s#2 1501.5 +(void()) cscroll() +(void()) main() +(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num) +(void*) memcpy::destination +(void*) memcpy::destination#2 +(byte*) memcpy::dst +(byte*) memcpy::dst#1 1.000000001E9 +(byte*) memcpy::dst#2 1.0033333346666667E9 +(byte*) memcpy::dst#4 2.0000002E7 +(word) memcpy::num +(void*) memcpy::return +(void*) memcpy::source +(void*) memcpy::source#2 +(byte*) memcpy::src +(byte*) memcpy::src#1 2.000000002E9 +(byte*) memcpy::src#2 1.00250000125E9 +(byte*) memcpy::src#4 1.0000001E7 +(byte*) memcpy::src_end +(byte*) memcpy::src_end#0 1.2625000025E8 +(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num) +(byte) memset::c +(byte) memset::c#4 1.42857143E8 +(byte*) memset::dst +(byte*) memset::dst#1 2.000000002E9 +(byte*) memset::dst#2 1.3366666683333335E9 +(byte*) memset::dst#4 2.0000002E7 +(byte*) memset::end +(byte*) memset::end#0 1.683333336666667E8 +(word) memset::num +(void*) memset::return +(void*) memset::str +(void*) memset::str#3 +(byte) printf_buffer_number::sign +(byte) printf_format_number::justify_left +(byte) printf_format_number::min_length +(byte) printf_format_number::radix +(byte) printf_format_number::sign_always +(byte) printf_format_number::upper_case +(byte) printf_format_number::zero_padding +(byte) printf_format_string::justify_left +(byte) printf_format_string::min_length + +Initial phi equivalence classes +[ cputs::s#2 cputs::s#0 ] +[ memcpy::source#2 ] +[ memcpy::destination#2 ] +[ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +[ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] +[ memset::str#3 ] +[ memset::c#4 ] +[ memset::dst#2 memset::dst#4 memset::dst#1 ] +Added variable conio_cursor_x to live range equivalence class [ conio_cursor_x ] +Added variable conio_cursor_y to live range equivalence class [ conio_cursor_y ] +Added variable conio_line_text to live range equivalence class [ conio_line_text ] +Added variable conio_line_color to live range equivalence class [ conio_line_color ] +Added variable cputs::c#1 to live range equivalence class [ cputs::c#1 ] +Added variable cputc::c#0 to live range equivalence class [ cputc::c#0 ] +Added variable memcpy::src_end#0 to live range equivalence class [ memcpy::src_end#0 ] +Added variable memset::end#0 to live range equivalence class [ memset::end#0 ] +Complete equivalence classes +[ cputs::s#2 cputs::s#0 ] +[ memcpy::source#2 ] +[ memcpy::destination#2 ] +[ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +[ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] +[ memset::str#3 ] +[ memset::c#4 ] +[ memset::dst#2 memset::dst#4 memset::dst#1 ] +[ conio_cursor_x ] +[ conio_cursor_y ] +[ conio_line_text ] +[ conio_line_color ] +[ cputs::c#1 ] +[ cputc::c#0 ] +[ memcpy::src_end#0 ] +[ memset::end#0 ] +Allocated zp[2]:2 [ cputs::s#2 cputs::s#0 ] +Allocated zp[2]:4 [ memcpy::source#2 ] +Allocated zp[2]:6 [ memcpy::destination#2 ] +Allocated zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +Allocated zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] +Allocated zp[2]:12 [ memset::str#3 ] +Allocated zp[1]:14 [ memset::c#4 ] +Allocated zp[2]:15 [ memset::dst#2 memset::dst#4 memset::dst#1 ] +Allocated zp[1]:17 [ conio_cursor_x ] +Allocated zp[1]:18 [ conio_cursor_y ] +Allocated zp[2]:19 [ conio_line_text ] +Allocated zp[2]:21 [ conio_line_color ] +Allocated zp[1]:23 [ cputs::c#1 ] +Allocated zp[1]:24 [ cputc::c#0 ] +Allocated zp[2]:25 [ memcpy::src_end#0 ] +Allocated zp[2]:27 [ memset::end#0 ] + +INITIAL ASM +Target platform is mega65 / MEGA45GS02 + // File Comments +// Hello World for MEGA 65 - using stdio.h and conio.h +// Functions for performing input and output. + // Upstart +.cpu _45gs02 + .file [name="helloworld-mega65.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$2001] +.segmentdef Code [start=$2017] +.segmentdef Data [startAfter="Code"] +.segment Basic +.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0 +.byte $15, $20, $14, $00, $9e, $20 // 20 SYS +.text toIntString(__start) // NNNN +.byte $00, $00, $00 // + // Global Constants & labels + // Map 2nd KB of colour RAM $DC00-$DFFF (hiding CIA's) + .const CRAM2K = 1 + .const LIGHT_BLUE = $e + // I/O Personality selection + .label IO_KEY = $d02f + // C65 Banking Register + .label IO_BANK = $d030 + // Color Ram + .label COLORRAM = $d800 + // Default address of screen character matrix + .label DEFAULT_SCREEN = $800 + // The number of bytes on the screen + // The current cursor x-position + .label conio_cursor_x = $11 + // The current cursor y-position + .label conio_cursor_y = $12 + // The current text cursor line start + .label conio_line_text = $13 + // The current color cursor line start + .label conio_line_color = $15 +.segment Code + // __start +__start: { + jmp __init1 + // __start::__init1 + __init1: + // [1] (byte) conio_cursor_x ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // [2] (byte) conio_cursor_y ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_y + // [3] (byte*) conio_line_text ← (const nomodify byte*) DEFAULT_SCREEN -- pbuz1=pbuc1 + lda #DEFAULT_SCREEN + sta.z conio_line_text+1 + // [4] (byte*) conio_line_color ← (const nomodify byte*) COLORRAM -- pbuz1=pbuc1 + lda #COLORRAM + sta.z conio_line_color+1 + // [5] call conio_mega65_init + //#pragma constructor + jsr conio_mega65_init + // [6] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] + __b1_from___init1: + jmp __b1 + // __start::@1 + __b1: + // [7] call main + // [15] phi from __start::@1 to main [phi:__start::@1->main] + main_from___b1: + jsr main + jmp __breturn + // __start::@return + __breturn: + // [8] return + rts +} + // conio_mega65_init +// Enable 2K Color ROM +conio_mega65_init: { + // asm { sei } + // Disable BASIC/KERNAL interrupts + sei + // asm { lda#0 tax tay taz map eom } + // Map memory to BANK 0 : 0x00XXXX - giving access to I/O + lda #0 + tax + tay + taz + map + eom + // [11] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $47 -- _deref_pbuc1=vbuc2 + // Enable the VIC 4 + lda #$47 + sta IO_KEY + // [12] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $53 -- _deref_pbuc1=vbuc2 + lda #$53 + sta IO_KEY + // [13] *((const nomodify to_volatile byte*) IO_BANK) ← *((const nomodify to_volatile byte*) IO_BANK) | (const nomodify byte) CRAM2K -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // Enable 2K Color RAM + lda #CRAM2K + ora IO_BANK + sta IO_BANK + jmp __breturn + // conio_mega65_init::@return + __breturn: + // [14] return + rts +} + // main +main: { + // [16] call cputs + // [18] phi from main to cputs [phi:main->cputs] + cputs_from_main: + jsr cputs + jmp __breturn + // main::@return + __breturn: + // [17] return + rts + .segment Data + s: .text "hello world!" + .byte 0 +} +.segment Code + // cputs +// Output a NUL-terminated string at the current cursor position +// cputs(byte* zp(2) s) +cputs: { + .label c = $17 + .label s = 2 + // [19] phi from cputs to cputs::@1 [phi:cputs->cputs::@1] + __b1_from_cputs: + // [19] phi (to_nomodify byte*) cputs::s#2 = (const byte*) main::s [phi:cputs->cputs::@1#0] -- pbuz1=pbuc1 + lda #main.s + sta.z s+1 + jmp __b1 + // cputs::@1 + __b1: + // [20] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2) -- vbuz1=_deref_pbuz2 + ldy #0 + lda (s),y + sta.z c + // [21] (to_nomodify byte*) cputs::s#0 ← ++ (to_nomodify byte*) cputs::s#2 -- pbuz1=_inc_pbuz1 + inw.z s + // [22] if((byte) 0!=(byte) cputs::c#1) goto cputs::@2 -- vbuc1_neq_vbuz1_then_la1 + lda #0 + cmp.z c + bne __b2 + jmp __breturn + // cputs::@return + __breturn: + // [23] return + rts + // cputs::@2 + __b2: + // [24] (byte) cputc::c#0 ← (byte) cputs::c#1 -- vbuz1=vbuz2 + lda.z c + sta.z cputc.c + // [25] call cputc + jsr cputc + // [19] phi from cputs::@2 to cputs::@1 [phi:cputs::@2->cputs::@1] + __b1_from___b2: + // [19] phi (to_nomodify byte*) cputs::s#2 = (to_nomodify byte*) cputs::s#0 [phi:cputs::@2->cputs::@1#0] -- register_copy + jmp __b1 +} + // cputc +// Output one character at the current cursor position +// Moves the cursor forward. Scrolls the entire screen if needed +// cputc(byte zp($18) c) +cputc: { + .label c = $18 + // [26] if((byte) cputc::c#0==(byte) ' ') goto cputc::@1 -- vbuz1_eq_vbuc1_then_la1 + lda #'\n' + cmp.z c + beq __b1_from_cputc + jmp __b2 + // cputc::@2 + __b2: + // [27] *((byte*) conio_line_text + (byte) conio_cursor_x) ← (byte) cputc::c#0 -- pbuz1_derefidx_vbuz2=vbuz3 + lda.z c + ldy.z conio_cursor_x + sta (conio_line_text),y + // [28] *((byte*) conio_line_color + (byte) conio_cursor_x) ← (const nomodify byte) LIGHT_BLUE -- pbuz1_derefidx_vbuz2=vbuc1 + lda #LIGHT_BLUE + ldy.z conio_cursor_x + sta (conio_line_color),y + // [29] (byte) conio_cursor_x ← ++ (byte) conio_cursor_x -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_x + // [30] if((byte) conio_cursor_x!=(byte) $50) goto cputc::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$50 + cmp.z conio_cursor_x + bne __breturn + // [31] phi from cputc::@2 to cputc::@3 [phi:cputc::@2->cputc::@3] + __b3_from___b2: + jmp __b3 + // cputc::@3 + __b3: + // [32] call cputln + jsr cputln + jmp __breturn + // cputc::@return + __breturn: + // [33] return + rts + // [34] phi from cputc to cputc::@1 [phi:cputc->cputc::@1] + __b1_from_cputc: + jmp __b1 + // cputc::@1 + __b1: + // [35] call cputln + jsr cputln + jmp __breturn +} + // cputln +// Print a newline +cputln: { + // [36] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $50 -- pbuz1=pbuz1_plus_vbuc1 + lda #$50 + clc + adc.z conio_line_text + sta.z conio_line_text + bcc !+ + inc.z conio_line_text+1 + !: + // [37] (byte*) conio_line_color ← (byte*) conio_line_color + (byte) $50 -- pbuz1=pbuz1_plus_vbuc1 + lda #$50 + clc + adc.z conio_line_color + sta.z conio_line_color + bcc !+ + inc.z conio_line_color+1 + !: + // [38] (byte) conio_cursor_x ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // [39] (byte) conio_cursor_y ← ++ (byte) conio_cursor_y -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_y + // [40] call cscroll + jsr cscroll + jmp __breturn + // cputln::@return + __breturn: + // [41] return + rts +} + // cscroll +// Scroll the entire screen if the cursor is beyond the last line +cscroll: { + // [42] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$19 + cmp.z conio_cursor_y + bne __breturn + // [43] phi from cscroll to cscroll::@1 [phi:cscroll->cscroll::@1] + __b1_from_cscroll: + jmp __b1 + // cscroll::@1 + __b1: + // [44] call memcpy + // [55] phi from cscroll::@1 to memcpy [phi:cscroll::@1->memcpy] + memcpy_from___b1: + // [55] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) DEFAULT_SCREEN [phi:cscroll::@1->memcpy#0] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN + sta.z memcpy.destination+1 + // [55] phi (void*) memcpy::source#2 = (void*)(const nomodify byte*) DEFAULT_SCREEN+(byte) $50 [phi:cscroll::@1->memcpy#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$50 + sta.z memcpy.source+1 + jsr memcpy + // [45] phi from cscroll::@1 to cscroll::@2 [phi:cscroll::@1->cscroll::@2] + __b2_from___b1: + jmp __b2 + // cscroll::@2 + __b2: + // [46] call memcpy + // [55] phi from cscroll::@2 to memcpy [phi:cscroll::@2->memcpy] + memcpy_from___b2: + // [55] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) COLORRAM [phi:cscroll::@2->memcpy#0] -- pvoz1=pvoc1 + lda #COLORRAM + sta.z memcpy.destination+1 + // [55] phi (void*) memcpy::source#2 = (void*)(const nomodify byte*) COLORRAM+(byte) $50 [phi:cscroll::@2->memcpy#1] -- pvoz1=pvoc1 + lda #COLORRAM+$50 + sta.z memcpy.source+1 + jsr memcpy + // [47] phi from cscroll::@2 to cscroll::@3 [phi:cscroll::@2->cscroll::@3] + __b3_from___b2: + jmp __b3 + // cscroll::@3 + __b3: + // [48] call memset + // [65] phi from cscroll::@3 to memset [phi:cscroll::@3->memset] + memset_from___b3: + // [65] phi (byte) memset::c#4 = (byte) ' ' [phi:cscroll::@3->memset#0] -- vbuz1=vbuc1 + lda #' ' + sta.z memset.c + // [65] phi (void*) memset::str#3 = (void*)(const nomodify byte*) DEFAULT_SCREEN+(word)(number) $19*(number) $50-(byte) $50 [phi:cscroll::@3->memset#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$19*$50-$50 + sta.z memset.str+1 + jsr memset + // [49] phi from cscroll::@3 to cscroll::@4 [phi:cscroll::@3->cscroll::@4] + __b4_from___b3: + jmp __b4 + // cscroll::@4 + __b4: + // [50] call memset + // [65] phi from cscroll::@4 to memset [phi:cscroll::@4->memset] + memset_from___b4: + // [65] phi (byte) memset::c#4 = (const nomodify byte) LIGHT_BLUE [phi:cscroll::@4->memset#0] -- vbuz1=vbuc1 + lda #LIGHT_BLUE + sta.z memset.c + // [65] phi (void*) memset::str#3 = (void*)(const nomodify byte*) COLORRAM+(word)(number) $19*(number) $50-(byte) $50 [phi:cscroll::@4->memset#1] -- pvoz1=pvoc1 + lda #COLORRAM+$19*$50-$50 + sta.z memset.str+1 + jsr memset + jmp __b5 + // cscroll::@5 + __b5: + // [51] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $50 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_text + sbc #$50 + sta.z conio_line_text + lda.z conio_line_text+1 + sbc #0 + sta.z conio_line_text+1 + // [52] (byte*) conio_line_color ← (byte*) conio_line_color - (byte) $50 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_color + sbc #$50 + sta.z conio_line_color + lda.z conio_line_color+1 + sbc #0 + sta.z conio_line_color+1 + // [53] (byte) conio_cursor_y ← -- (byte) conio_cursor_y -- vbuz1=_dec_vbuz1 + dec.z conio_cursor_y + jmp __breturn + // cscroll::@return + __breturn: + // [54] return + rts +} + // memcpy +// Copy block of memory (forwards) +// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. +// memcpy(void* zp(6) destination, void* zp(4) source) +memcpy: { + .label src_end = $19 + .label dst = $a + .label src = 8 + .label source = 4 + .label destination = 6 + // [56] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word)(number) $19*(number) $50-(number) $50 -- pbuz1=pbuz2_plus_vwuc1 + lda.z source + clc + adc #<$19*$50-$50 + sta.z src_end + lda.z source+1 + adc #>$19*$50-$50 + sta.z src_end+1 + // [57] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 -- pbuz1=pbuz2 + lda.z source + sta.z src + lda.z source+1 + sta.z src+1 + // [58] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 -- pbuz1=pbuz2 + lda.z destination + sta.z dst + lda.z destination+1 + sta.z dst+1 + // [59] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1] + __b1_from_memcpy: + __b1_from___b2: + // [59] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy + // [59] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy + jmp __b1 + // memcpy::@1 + __b1: + // [60] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 + lda.z src+1 + cmp.z src_end+1 + bne __b2 + lda.z src + cmp.z src_end + bne __b2 + jmp __breturn + // memcpy::@return + __breturn: + // [61] return + rts + // memcpy::@2 + __b2: + // [62] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (src),y + ldy #0 + sta (dst),y + // [63] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 + inw.z dst + // [64] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1 + inw.z src + jmp __b1_from___b2 +} + // memset +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +// memset(void* zp($c) str, byte zp($e) c) +memset: { + .label end = $1b + .label dst = $f + .label str = $c + .label c = $e + jmp __b1 + // memset::@1 + __b1: + // [66] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (byte) $50 -- pbuz1=pbuz2_plus_vbuc1 + lda #$50 + clc + adc.z str + sta.z end + lda #0 + adc.z str+1 + sta.z end+1 + // [67] (byte*) memset::dst#4 ← (byte*)(void*) memset::str#3 -- pbuz1=pbuz2 + lda.z str + sta.z dst + lda.z str+1 + sta.z dst+1 + // [68] phi from memset::@1 memset::@3 to memset::@2 [phi:memset::@1/memset::@3->memset::@2] + __b2_from___b1: + __b2_from___b3: + // [68] phi (byte*) memset::dst#2 = (byte*) memset::dst#4 [phi:memset::@1/memset::@3->memset::@2#0] -- register_copy + jmp __b2 + // memset::@2 + __b2: + // [69] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3 -- pbuz1_neq_pbuz2_then_la1 + lda.z dst+1 + cmp.z end+1 + bne __b3 + lda.z dst + cmp.z end + bne __b3 + jmp __breturn + // memset::@return + __breturn: + // [70] return + rts + // memset::@3 + __b3: + // [71] *((byte*) memset::dst#2) ← (byte) memset::c#4 -- _deref_pbuz1=vbuz2 + lda.z c + ldy #0 + sta (dst),y + // [72] (byte*) memset::dst#1 ← ++ (byte*) memset::dst#2 -- pbuz1=_inc_pbuz1 + inw.z dst + jmp __b2_from___b3 +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [1] (byte) conio_cursor_x ← (byte) 0 [ conio_cursor_x ] ( [ conio_cursor_x ] { } ) always clobbers reg byte a +Statement [2] (byte) conio_cursor_y ← (byte) 0 [ conio_cursor_x conio_cursor_y ] ( [ conio_cursor_x conio_cursor_y ] { } ) always clobbers reg byte a +Statement [3] (byte*) conio_line_text ← (const nomodify byte*) DEFAULT_SCREEN [ conio_cursor_x conio_cursor_y conio_line_text ] ( [ conio_cursor_x conio_cursor_y conio_line_text ] { } ) always clobbers reg byte a +Statement [4] (byte*) conio_line_color ← (const nomodify byte*) COLORRAM [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a +Statement asm { lda#0 tax tay taz map eom } always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [11] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $47 [ ] ( [ ] { } conio_mega65_init:5 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a +Statement [12] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $53 [ ] ( [ ] { } conio_mega65_init:5 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a +Statement [13] *((const nomodify to_volatile byte*) IO_BANK) ← *((const nomodify to_volatile byte*) IO_BANK) | (const nomodify byte) CRAM2K [ ] ( [ ] { } conio_mega65_init:5 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a +Statement [20] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2) [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#2 cputs::c#1 ] ( main:7::cputs:16 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#2 cputs::c#1 ] { } ) always clobbers reg byte a reg byte y +Statement [28] *((byte*) conio_line_color + (byte) conio_cursor_x) ← (const nomodify byte) LIGHT_BLUE [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Statement [30] if((byte) conio_cursor_x!=(byte) $50) goto cputc::@return [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [36] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $50 [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [37] (byte*) conio_line_color ← (byte*) conio_line_color + (byte) $50 [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [38] (byte) conio_cursor_x ← (byte) 0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [42] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [51] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $50 [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [52] (byte*) conio_line_color ← (byte*) conio_line_color - (byte) $50 [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [56] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word)(number) $19*(number) $50-(number) $50 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [57] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [58] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [60] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [62] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Statement [66] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (byte) $50 [ memset::str#3 memset::c#4 memset::end#0 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:14 [ memset::c#4 ] +Statement [67] (byte*) memset::dst#4 ← (byte*)(void*) memset::str#3 [ memset::c#4 memset::end#0 memset::dst#4 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [69] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3 [ memset::c#4 memset::end#0 memset::dst#2 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [71] *((byte*) memset::dst#2) ← (byte) memset::c#4 [ memset::c#4 memset::end#0 memset::dst#2 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Removing always clobbered register reg byte y as potential for zp[1]:14 [ memset::c#4 ] +Statement [1] (byte) conio_cursor_x ← (byte) 0 [ conio_cursor_x ] ( [ conio_cursor_x ] { } ) always clobbers reg byte a +Statement [2] (byte) conio_cursor_y ← (byte) 0 [ conio_cursor_x conio_cursor_y ] ( [ conio_cursor_x conio_cursor_y ] { } ) always clobbers reg byte a +Statement [3] (byte*) conio_line_text ← (const nomodify byte*) DEFAULT_SCREEN [ conio_cursor_x conio_cursor_y conio_line_text ] ( [ conio_cursor_x conio_cursor_y conio_line_text ] { } ) always clobbers reg byte a +Statement [4] (byte*) conio_line_color ← (const nomodify byte*) COLORRAM [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a +Statement asm { lda#0 tax tay taz map eom } always clobbers reg byte a reg byte x reg byte y reg byte z +Statement [11] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $47 [ ] ( [ ] { } conio_mega65_init:5 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a +Statement [12] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $53 [ ] ( [ ] { } conio_mega65_init:5 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a +Statement [13] *((const nomodify to_volatile byte*) IO_BANK) ← *((const nomodify to_volatile byte*) IO_BANK) | (const nomodify byte) CRAM2K [ ] ( [ ] { } conio_mega65_init:5 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a +Statement [20] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2) [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#2 cputs::c#1 ] ( main:7::cputs:16 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#2 cputs::c#1 ] { } ) always clobbers reg byte a reg byte y +Statement [28] *((byte*) conio_line_color + (byte) conio_cursor_x) ← (const nomodify byte) LIGHT_BLUE [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Statement [30] if((byte) conio_cursor_x!=(byte) $50) goto cputc::@return [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [36] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $50 [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [37] (byte*) conio_line_color ← (byte*) conio_line_color + (byte) $50 [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35 [ cputs::s#0 conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [38] (byte) conio_cursor_x ← (byte) 0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [42] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [51] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $50 [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [52] (byte*) conio_line_color ← (byte*) conio_line_color - (byte) $50 [ conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [56] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word)(number) $19*(number) $50-(number) $50 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [57] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [58] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [60] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [62] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:44 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memcpy:46 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Statement [66] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (byte) $50 [ memset::str#3 memset::c#4 memset::end#0 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::str#3 memset::c#4 memset::end#0 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [67] (byte*) memset::dst#4 ← (byte*)(void*) memset::str#3 [ memset::c#4 memset::end#0 memset::dst#4 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#4 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [69] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3 [ memset::c#4 memset::end#0 memset::dst#2 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a +Statement [71] *((byte*) memset::dst#2) ← (byte) memset::c#4 [ memset::c#4 memset::end#0 memset::dst#2 ] ( main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:48 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:32::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } main:7::cputs:16::cputc:25::cputln:35::cscroll:40::memset:50 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color memset::c#4 memset::end#0 memset::dst#2 ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y +Potential registers zp[2]:2 [ cputs::s#2 cputs::s#0 ] : zp[2]:2 , +Potential registers zp[2]:4 [ memcpy::source#2 ] : zp[2]:4 , +Potential registers zp[2]:6 [ memcpy::destination#2 ] : zp[2]:6 , +Potential registers zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] : zp[2]:8 , +Potential registers zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] : zp[2]:10 , +Potential registers zp[2]:12 [ memset::str#3 ] : zp[2]:12 , +Potential registers zp[1]:14 [ memset::c#4 ] : zp[1]:14 , reg byte x , reg byte z , +Potential registers zp[2]:15 [ memset::dst#2 memset::dst#4 memset::dst#1 ] : zp[2]:15 , +Potential registers zp[1]:17 [ conio_cursor_x ] : zp[1]:17 , +Potential registers zp[1]:18 [ conio_cursor_y ] : zp[1]:18 , +Potential registers zp[2]:19 [ conio_line_text ] : zp[2]:19 , +Potential registers zp[2]:21 [ conio_line_color ] : zp[2]:21 , +Potential registers zp[1]:23 [ cputs::c#1 ] : zp[1]:23 , reg byte a , reg byte x , reg byte y , reg byte z , +Potential registers zp[1]:24 [ cputc::c#0 ] : zp[1]:24 , reg byte a , reg byte x , reg byte y , reg byte z , +Potential registers zp[2]:25 [ memcpy::src_end#0 ] : zp[2]:25 , +Potential registers zp[2]:27 [ memset::end#0 ] : zp[2]:27 , + +REGISTER UPLIFT SCOPES +Uplift Scope [memcpy] 3,012,500,004.25: zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] 2,023,333,337.67: zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] 126,250,000.25: zp[2]:25 [ memcpy::src_end#0 ] 0: zp[2]:4 [ memcpy::source#2 ] 0: zp[2]:6 [ memcpy::destination#2 ] +Uplift Scope [memset] 3,356,666,672.33: zp[2]:15 [ memset::dst#2 memset::dst#4 memset::dst#1 ] 168,333,333.67: zp[2]:27 [ memset::end#0 ] 142,857,143: zp[1]:14 [ memset::c#4 ] 0: zp[2]:12 [ memset::str#3 ] +Uplift Scope [] 76,190.64: zp[1]:18 [ conio_cursor_y ] 55,250.18: zp[2]:21 [ conio_line_color ] 53,902.61: zp[2]:19 [ conio_line_text ] 5,769.54: zp[1]:17 [ conio_cursor_x ] +Uplift Scope [cputc] 10,501.5: zp[1]:24 [ cputc::c#0 ] +Uplift Scope [cputs] 2,002: zp[2]:2 [ cputs::s#2 cputs::s#0 ] 1,001: zp[1]:23 [ cputs::c#1 ] +Uplift Scope [RADIX] +Uplift Scope [MOS6526_CIA] +Uplift Scope [MOS6569_VICII] +Uplift Scope [MOS6581_SID] +Uplift Scope [cputln] +Uplift Scope [cscroll] +Uplift Scope [conio_mega65_init] +Uplift Scope [printf_format_number] +Uplift Scope [printf_buffer_number] +Uplift Scope [printf_format_string] +Uplift Scope [main] +Uplift Scope [__start] + +Uplifting [memcpy] best 10452 combination zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] zp[2]:25 [ memcpy::src_end#0 ] zp[2]:4 [ memcpy::source#2 ] zp[2]:6 [ memcpy::destination#2 ] +Uplifting [memset] best 10246 combination zp[2]:15 [ memset::dst#2 memset::dst#4 memset::dst#1 ] zp[2]:27 [ memset::end#0 ] reg byte z [ memset::c#4 ] zp[2]:12 [ memset::str#3 ] +Uplifting [] best 10246 combination zp[1]:18 [ conio_cursor_y ] zp[2]:21 [ conio_line_color ] zp[2]:19 [ conio_line_text ] zp[1]:17 [ conio_cursor_x ] +Uplifting [cputc] best 10210 combination reg byte a [ cputc::c#0 ] +Uplifting [cputs] best 10120 combination zp[2]:2 [ cputs::s#2 cputs::s#0 ] reg byte a [ cputs::c#1 ] +Uplifting [RADIX] best 10120 combination +Uplifting [MOS6526_CIA] best 10120 combination +Uplifting [MOS6569_VICII] best 10120 combination +Uplifting [MOS6581_SID] best 10120 combination +Uplifting [cputln] best 10120 combination +Uplifting [cscroll] best 10120 combination +Uplifting [conio_mega65_init] best 10120 combination +Uplifting [printf_format_number] best 10120 combination +Uplifting [printf_buffer_number] best 10120 combination +Uplifting [printf_format_string] best 10120 combination +Uplifting [main] best 10120 combination +Uplifting [__start] best 10120 combination +Attempting to uplift remaining variables inzp[1]:18 [ conio_cursor_y ] +Uplifting [] best 10120 combination zp[1]:18 [ conio_cursor_y ] +Attempting to uplift remaining variables inzp[1]:17 [ conio_cursor_x ] +Uplifting [] best 10120 combination zp[1]:17 [ conio_cursor_x ] +Coalescing zero page register [ zp[2]:4 [ memcpy::source#2 ] ] with [ zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] - score: 1 +Coalescing zero page register [ zp[2]:6 [ memcpy::destination#2 ] ] with [ zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] - score: 1 +Coalescing zero page register [ zp[2]:12 [ memset::str#3 ] ] with [ zp[2]:15 [ memset::dst#2 memset::dst#4 memset::dst#1 ] ] - score: 1 +Coalescing zero page register [ zp[2]:12 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 ] ] with [ zp[2]:4 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] +Coalescing zero page register [ zp[2]:27 [ memset::end#0 ] ] with [ zp[2]:6 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] +Allocated (was zp[2]:12) zp[2]:4 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +Allocated (was zp[1]:17) zp[1]:6 [ conio_cursor_x ] +Allocated (was zp[1]:18) zp[1]:7 [ conio_cursor_y ] +Allocated (was zp[2]:19) zp[2]:8 [ conio_line_text ] +Allocated (was zp[2]:21) zp[2]:10 [ conio_line_color ] +Allocated (was zp[2]:25) zp[2]:12 [ memcpy::src_end#0 ] +Allocated (was zp[2]:27) zp[2]:14 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Hello World for MEGA 65 - using stdio.h and conio.h +// Functions for performing input and output. + // Upstart +.cpu _45gs02 + .file [name="helloworld-mega65.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$2001] +.segmentdef Code [start=$2017] +.segmentdef Data [startAfter="Code"] +.segment Basic +.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0 +.byte $15, $20, $14, $00, $9e, $20 // 20 SYS +.text toIntString(__start) // NNNN +.byte $00, $00, $00 // + // Global Constants & labels + // Map 2nd KB of colour RAM $DC00-$DFFF (hiding CIA's) + .const CRAM2K = 1 + .const LIGHT_BLUE = $e + // I/O Personality selection + .label IO_KEY = $d02f + // C65 Banking Register + .label IO_BANK = $d030 + // Color Ram + .label COLORRAM = $d800 + // Default address of screen character matrix + .label DEFAULT_SCREEN = $800 + // The number of bytes on the screen + // The current cursor x-position + .label conio_cursor_x = 6 + // The current cursor y-position + .label conio_cursor_y = 7 + // The current text cursor line start + .label conio_line_text = 8 + // The current color cursor line start + .label conio_line_color = $a +.segment Code + // __start +__start: { + jmp __init1 + // __start::__init1 + __init1: + // [1] (byte) conio_cursor_x ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // [2] (byte) conio_cursor_y ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_y + // [3] (byte*) conio_line_text ← (const nomodify byte*) DEFAULT_SCREEN -- pbuz1=pbuc1 + lda #DEFAULT_SCREEN + sta.z conio_line_text+1 + // [4] (byte*) conio_line_color ← (const nomodify byte*) COLORRAM -- pbuz1=pbuc1 + lda #COLORRAM + sta.z conio_line_color+1 + // [5] call conio_mega65_init + //#pragma constructor + jsr conio_mega65_init + // [6] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] + __b1_from___init1: + jmp __b1 + // __start::@1 + __b1: + // [7] call main + // [15] phi from __start::@1 to main [phi:__start::@1->main] + main_from___b1: + jsr main + jmp __breturn + // __start::@return + __breturn: + // [8] return + rts +} + // conio_mega65_init +// Enable 2K Color ROM +conio_mega65_init: { + // asm { sei } + // Disable BASIC/KERNAL interrupts + sei + // asm { lda#0 tax tay taz map eom } + // Map memory to BANK 0 : 0x00XXXX - giving access to I/O + lda #0 + tax + tay + taz + map + eom + // [11] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $47 -- _deref_pbuc1=vbuc2 + // Enable the VIC 4 + lda #$47 + sta IO_KEY + // [12] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $53 -- _deref_pbuc1=vbuc2 + lda #$53 + sta IO_KEY + // [13] *((const nomodify to_volatile byte*) IO_BANK) ← *((const nomodify to_volatile byte*) IO_BANK) | (const nomodify byte) CRAM2K -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // Enable 2K Color RAM + lda #CRAM2K + ora IO_BANK + sta IO_BANK + jmp __breturn + // conio_mega65_init::@return + __breturn: + // [14] return + rts +} + // main +main: { + // [16] call cputs + // [18] phi from main to cputs [phi:main->cputs] + cputs_from_main: + jsr cputs + jmp __breturn + // main::@return + __breturn: + // [17] return + rts + .segment Data + s: .text "hello world!" + .byte 0 +} +.segment Code + // cputs +// Output a NUL-terminated string at the current cursor position +// cputs(byte* zp(2) s) +cputs: { + .label s = 2 + // [19] phi from cputs to cputs::@1 [phi:cputs->cputs::@1] + __b1_from_cputs: + // [19] phi (to_nomodify byte*) cputs::s#2 = (const byte*) main::s [phi:cputs->cputs::@1#0] -- pbuz1=pbuc1 + lda #main.s + sta.z s+1 + jmp __b1 + // cputs::@1 + __b1: + // [20] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2) -- vbuaa=_deref_pbuz1 + ldy #0 + lda (s),y + // [21] (to_nomodify byte*) cputs::s#0 ← ++ (to_nomodify byte*) cputs::s#2 -- pbuz1=_inc_pbuz1 + inw.z s + // [22] if((byte) 0!=(byte) cputs::c#1) goto cputs::@2 -- vbuc1_neq_vbuaa_then_la1 + cmp #0 + bne __b2 + jmp __breturn + // cputs::@return + __breturn: + // [23] return + rts + // cputs::@2 + __b2: + // [24] (byte) cputc::c#0 ← (byte) cputs::c#1 + // [25] call cputc + jsr cputc + // [19] phi from cputs::@2 to cputs::@1 [phi:cputs::@2->cputs::@1] + __b1_from___b2: + // [19] phi (to_nomodify byte*) cputs::s#2 = (to_nomodify byte*) cputs::s#0 [phi:cputs::@2->cputs::@1#0] -- register_copy + jmp __b1 +} + // cputc +// Output one character at the current cursor position +// Moves the cursor forward. Scrolls the entire screen if needed +// cputc(byte register(A) c) +cputc: { + // [26] if((byte) cputc::c#0==(byte) ' ') goto cputc::@1 -- vbuaa_eq_vbuc1_then_la1 + cmp #'\n' + beq __b1_from_cputc + jmp __b2 + // cputc::@2 + __b2: + // [27] *((byte*) conio_line_text + (byte) conio_cursor_x) ← (byte) cputc::c#0 -- pbuz1_derefidx_vbuz2=vbuaa + ldy.z conio_cursor_x + sta (conio_line_text),y + // [28] *((byte*) conio_line_color + (byte) conio_cursor_x) ← (const nomodify byte) LIGHT_BLUE -- pbuz1_derefidx_vbuz2=vbuc1 + lda #LIGHT_BLUE + ldy.z conio_cursor_x + sta (conio_line_color),y + // [29] (byte) conio_cursor_x ← ++ (byte) conio_cursor_x -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_x + // [30] if((byte) conio_cursor_x!=(byte) $50) goto cputc::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$50 + cmp.z conio_cursor_x + bne __breturn + // [31] phi from cputc::@2 to cputc::@3 [phi:cputc::@2->cputc::@3] + __b3_from___b2: + jmp __b3 + // cputc::@3 + __b3: + // [32] call cputln + jsr cputln + jmp __breturn + // cputc::@return + __breturn: + // [33] return + rts + // [34] phi from cputc to cputc::@1 [phi:cputc->cputc::@1] + __b1_from_cputc: + jmp __b1 + // cputc::@1 + __b1: + // [35] call cputln + jsr cputln + jmp __breturn +} + // cputln +// Print a newline +cputln: { + // [36] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $50 -- pbuz1=pbuz1_plus_vbuc1 + lda #$50 + clc + adc.z conio_line_text + sta.z conio_line_text + bcc !+ + inc.z conio_line_text+1 + !: + // [37] (byte*) conio_line_color ← (byte*) conio_line_color + (byte) $50 -- pbuz1=pbuz1_plus_vbuc1 + lda #$50 + clc + adc.z conio_line_color + sta.z conio_line_color + bcc !+ + inc.z conio_line_color+1 + !: + // [38] (byte) conio_cursor_x ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // [39] (byte) conio_cursor_y ← ++ (byte) conio_cursor_y -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_y + // [40] call cscroll + jsr cscroll + jmp __breturn + // cputln::@return + __breturn: + // [41] return + rts +} + // cscroll +// Scroll the entire screen if the cursor is beyond the last line +cscroll: { + // [42] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$19 + cmp.z conio_cursor_y + bne __breturn + // [43] phi from cscroll to cscroll::@1 [phi:cscroll->cscroll::@1] + __b1_from_cscroll: + jmp __b1 + // cscroll::@1 + __b1: + // [44] call memcpy + // [55] phi from cscroll::@1 to memcpy [phi:cscroll::@1->memcpy] + memcpy_from___b1: + // [55] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) DEFAULT_SCREEN [phi:cscroll::@1->memcpy#0] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN + sta.z memcpy.destination+1 + // [55] phi (void*) memcpy::source#2 = (void*)(const nomodify byte*) DEFAULT_SCREEN+(byte) $50 [phi:cscroll::@1->memcpy#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$50 + sta.z memcpy.source+1 + jsr memcpy + // [45] phi from cscroll::@1 to cscroll::@2 [phi:cscroll::@1->cscroll::@2] + __b2_from___b1: + jmp __b2 + // cscroll::@2 + __b2: + // [46] call memcpy + // [55] phi from cscroll::@2 to memcpy [phi:cscroll::@2->memcpy] + memcpy_from___b2: + // [55] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) COLORRAM [phi:cscroll::@2->memcpy#0] -- pvoz1=pvoc1 + lda #COLORRAM + sta.z memcpy.destination+1 + // [55] phi (void*) memcpy::source#2 = (void*)(const nomodify byte*) COLORRAM+(byte) $50 [phi:cscroll::@2->memcpy#1] -- pvoz1=pvoc1 + lda #COLORRAM+$50 + sta.z memcpy.source+1 + jsr memcpy + // [47] phi from cscroll::@2 to cscroll::@3 [phi:cscroll::@2->cscroll::@3] + __b3_from___b2: + jmp __b3 + // cscroll::@3 + __b3: + // [48] call memset + // [65] phi from cscroll::@3 to memset [phi:cscroll::@3->memset] + memset_from___b3: + // [65] phi (byte) memset::c#4 = (byte) ' ' [phi:cscroll::@3->memset#0] -- vbuzz=vbuc1 + ldz #' ' + // [65] phi (void*) memset::str#3 = (void*)(const nomodify byte*) DEFAULT_SCREEN+(word)(number) $19*(number) $50-(byte) $50 [phi:cscroll::@3->memset#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$19*$50-$50 + sta.z memset.str+1 + jsr memset + // [49] phi from cscroll::@3 to cscroll::@4 [phi:cscroll::@3->cscroll::@4] + __b4_from___b3: + jmp __b4 + // cscroll::@4 + __b4: + // [50] call memset + // [65] phi from cscroll::@4 to memset [phi:cscroll::@4->memset] + memset_from___b4: + // [65] phi (byte) memset::c#4 = (const nomodify byte) LIGHT_BLUE [phi:cscroll::@4->memset#0] -- vbuzz=vbuc1 + ldz #LIGHT_BLUE + // [65] phi (void*) memset::str#3 = (void*)(const nomodify byte*) COLORRAM+(word)(number) $19*(number) $50-(byte) $50 [phi:cscroll::@4->memset#1] -- pvoz1=pvoc1 + lda #COLORRAM+$19*$50-$50 + sta.z memset.str+1 + jsr memset + jmp __b5 + // cscroll::@5 + __b5: + // [51] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $50 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_text + sbc #$50 + sta.z conio_line_text + lda.z conio_line_text+1 + sbc #0 + sta.z conio_line_text+1 + // [52] (byte*) conio_line_color ← (byte*) conio_line_color - (byte) $50 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_color + sbc #$50 + sta.z conio_line_color + lda.z conio_line_color+1 + sbc #0 + sta.z conio_line_color+1 + // [53] (byte) conio_cursor_y ← -- (byte) conio_cursor_y -- vbuz1=_dec_vbuz1 + dec.z conio_cursor_y + jmp __breturn + // cscroll::@return + __breturn: + // [54] return + rts +} + // memcpy +// Copy block of memory (forwards) +// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. +// memcpy(void* zp($e) destination, void* zp(4) source) +memcpy: { + .label src_end = $c + .label dst = $e + .label src = 4 + .label source = 4 + .label destination = $e + // [56] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word)(number) $19*(number) $50-(number) $50 -- pbuz1=pbuz2_plus_vwuc1 + lda.z source + clc + adc #<$19*$50-$50 + sta.z src_end + lda.z source+1 + adc #>$19*$50-$50 + sta.z src_end+1 + // [57] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 + // [58] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 + // [59] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1] + __b1_from_memcpy: + __b1_from___b2: + // [59] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy + // [59] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy + jmp __b1 + // memcpy::@1 + __b1: + // [60] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 + lda.z src+1 + cmp.z src_end+1 + bne __b2 + lda.z src + cmp.z src_end + bne __b2 + jmp __breturn + // memcpy::@return + __breturn: + // [61] return + rts + // memcpy::@2 + __b2: + // [62] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (src),y + ldy #0 + sta (dst),y + // [63] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 + inw.z dst + // [64] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1 + inw.z src + jmp __b1_from___b2 +} + // memset +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +// memset(void* zp(4) str, byte register(Z) c) +memset: { + .label end = $e + .label dst = 4 + .label str = 4 + jmp __b1 + // memset::@1 + __b1: + // [66] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (byte) $50 -- pbuz1=pbuz2_plus_vbuc1 + lda #$50 + clc + adc.z str + sta.z end + lda #0 + adc.z str+1 + sta.z end+1 + // [67] (byte*) memset::dst#4 ← (byte*)(void*) memset::str#3 + // [68] phi from memset::@1 memset::@3 to memset::@2 [phi:memset::@1/memset::@3->memset::@2] + __b2_from___b1: + __b2_from___b3: + // [68] phi (byte*) memset::dst#2 = (byte*) memset::dst#4 [phi:memset::@1/memset::@3->memset::@2#0] -- register_copy + jmp __b2 + // memset::@2 + __b2: + // [69] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3 -- pbuz1_neq_pbuz2_then_la1 + lda.z dst+1 + cmp.z end+1 + bne __b3 + lda.z dst + cmp.z end + bne __b3 + jmp __breturn + // memset::@return + __breturn: + // [70] return + rts + // memset::@3 + __b3: + // [71] *((byte*) memset::dst#2) ← (byte) memset::c#4 -- _deref_pbuz1=vbuzz + tza + ldy #0 + sta (dst),y + // [72] (byte*) memset::dst#1 ← ++ (byte*) memset::dst#2 -- pbuz1=_inc_pbuz1 + inw.z dst + jmp __b2_from___b3 +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __init1 +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __b2 +Removing instruction jmp __b3 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __b2 +Removing instruction jmp __b3 +Removing instruction jmp __b4 +Removing instruction jmp __b5 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __b1 +Removing instruction jmp __b2 +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction lda #0 +Removing instruction ldy.z conio_cursor_x +Removing instruction ldy #0 +Succesful ASM optimization Pass5UnnecesaryLoadElimination +Replacing label __b1_from_cputc with __b1 +Replacing label __b1_from___b2 with __b1 +Replacing label __b2_from___b3 with __b2 +Removing instruction __b1_from___init1: +Removing instruction main_from___b1: +Removing instruction __b3_from___b2: +Removing instruction __b1_from_cputc: +Removing instruction __b1_from_cscroll: +Removing instruction memcpy_from___b1: +Removing instruction __b2_from___b1: +Removing instruction memcpy_from___b2: +Removing instruction __b3_from___b2: +Removing instruction memset_from___b3: +Removing instruction __b4_from___b3: +Removing instruction memset_from___b4: +Removing instruction __b1_from_memcpy: +Removing instruction __b1_from___b2: +Removing instruction __b2_from___b1: +Removing instruction __b2_from___b3: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __init1: +Removing instruction __b1: +Removing instruction __breturn: +Removing instruction __breturn: +Removing instruction cputs_from_main: +Removing instruction __breturn: +Removing instruction __b1_from_cputs: +Removing instruction __breturn: +Removing instruction __b1_from___b2: +Removing instruction __b2: +Removing instruction __b3: +Removing instruction __breturn: +Removing instruction __b1: +Removing instruction __b2: +Removing instruction __b3: +Removing instruction __b4: +Removing instruction __b5: +Removing instruction __breturn: +Removing instruction __b1: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Replacing jump to rts with rts in jmp __breturn +Succesful ASM optimization Pass5DoubleJumpElimination + +FINAL SYMBOL TABLE +(const nomodify byte*) COLORRAM = (byte*) 55296 +(const nomodify byte) CRAM2K = (byte) 1 +(const nomodify byte*) DEFAULT_SCREEN = (byte*) 2048 +(const nomodify to_volatile byte*) IO_BANK = (byte*) 53296 +(const nomodify to_volatile byte*) IO_KEY = (byte*) 53295 +(const nomodify byte) LIGHT_BLUE = (byte) $e +(byte) MOS6526_CIA::INTERRUPT +(byte) MOS6526_CIA::PORT_A +(byte) MOS6526_CIA::PORT_A_DDR +(byte) MOS6526_CIA::PORT_B +(byte) MOS6526_CIA::PORT_B_DDR +(byte) MOS6526_CIA::SERIAL_DATA +(word) MOS6526_CIA::TIMER_A +(byte) MOS6526_CIA::TIMER_A_CONTROL +(word) MOS6526_CIA::TIMER_B +(byte) MOS6526_CIA::TIMER_B_CONTROL +(byte) MOS6526_CIA::TOD_10THS +(byte) MOS6526_CIA::TOD_HOURS +(byte) MOS6526_CIA::TOD_MIN +(byte) MOS6526_CIA::TOD_SEC +(byte) MOS6569_VICII::BG_COLOR +(byte) MOS6569_VICII::BG_COLOR1 +(byte) MOS6569_VICII::BG_COLOR2 +(byte) MOS6569_VICII::BG_COLOR3 +(byte) MOS6569_VICII::BORDER_COLOR +(byte) MOS6569_VICII::CONTROL1 +(byte) MOS6569_VICII::CONTROL2 +(byte) MOS6569_VICII::IRQ_ENABLE +(byte) MOS6569_VICII::IRQ_STATUS +(byte) MOS6569_VICII::LIGHTPEN_X +(byte) MOS6569_VICII::LIGHTPEN_Y +(byte) MOS6569_VICII::MEMORY +(byte) MOS6569_VICII::RASTER +(byte) MOS6569_VICII::SPRITE0_COLOR +(byte) MOS6569_VICII::SPRITE0_X +(byte) MOS6569_VICII::SPRITE0_Y +(byte) MOS6569_VICII::SPRITE1_COLOR +(byte) MOS6569_VICII::SPRITE1_X +(byte) MOS6569_VICII::SPRITE1_Y +(byte) MOS6569_VICII::SPRITE2_COLOR +(byte) MOS6569_VICII::SPRITE2_X +(byte) MOS6569_VICII::SPRITE2_Y +(byte) MOS6569_VICII::SPRITE3_COLOR +(byte) MOS6569_VICII::SPRITE3_X +(byte) MOS6569_VICII::SPRITE3_Y +(byte) MOS6569_VICII::SPRITE4_COLOR +(byte) MOS6569_VICII::SPRITE4_X +(byte) MOS6569_VICII::SPRITE4_Y +(byte) MOS6569_VICII::SPRITE5_COLOR +(byte) MOS6569_VICII::SPRITE5_X +(byte) MOS6569_VICII::SPRITE5_Y +(byte) MOS6569_VICII::SPRITE6_COLOR +(byte) MOS6569_VICII::SPRITE6_X +(byte) MOS6569_VICII::SPRITE6_Y +(byte) MOS6569_VICII::SPRITE7_COLOR +(byte) MOS6569_VICII::SPRITE7_X +(byte) MOS6569_VICII::SPRITE7_Y +(byte) MOS6569_VICII::SPRITES_BG_COLLISION +(byte) MOS6569_VICII::SPRITES_COLLISION +(byte) MOS6569_VICII::SPRITES_ENABLE +(byte) MOS6569_VICII::SPRITES_EXPAND_X +(byte) MOS6569_VICII::SPRITES_EXPAND_Y +(byte) MOS6569_VICII::SPRITES_MC +(byte) MOS6569_VICII::SPRITES_MCOLOR1 +(byte) MOS6569_VICII::SPRITES_MCOLOR2 +(byte) MOS6569_VICII::SPRITES_PRIORITY +(byte) MOS6569_VICII::SPRITES_XMSB +(byte) MOS6581_SID::CH1_ATTACK_DECAY +(byte) MOS6581_SID::CH1_CONTROL +(word) MOS6581_SID::CH1_FREQ +(word) MOS6581_SID::CH1_PULSE_WIDTH +(byte) MOS6581_SID::CH1_SUSTAIN_RELEASE +(byte) MOS6581_SID::CH2_ATTACK_DECAY +(byte) MOS6581_SID::CH2_CONTROL +(word) MOS6581_SID::CH2_FREQ +(word) MOS6581_SID::CH2_PULSE_WIDTH +(byte) MOS6581_SID::CH2_SUSTAIN_RELEASE +(byte) MOS6581_SID::CH3_ATTACK_DECAY +(byte) MOS6581_SID::CH3_CONTROL +(byte) MOS6581_SID::CH3_ENV +(word) MOS6581_SID::CH3_FREQ +(byte) MOS6581_SID::CH3_OSC +(word) MOS6581_SID::CH3_PULSE_WIDTH +(byte) MOS6581_SID::CH3_SUSTAIN_RELEASE +(byte) MOS6581_SID::FILTER_CUTOFF_HIGH +(byte) MOS6581_SID::FILTER_CUTOFF_LOW +(byte) MOS6581_SID::FILTER_SETUP +(byte) MOS6581_SID::POT_X +(byte) MOS6581_SID::POT_Y +(byte) MOS6581_SID::VOLUME_FILTER_MODE +(const byte) RADIX::BINARY = (number) 2 +(const byte) RADIX::DECIMAL = (number) $a +(const byte) RADIX::HEXADECIMAL = (number) $10 +(const byte) RADIX::OCTAL = (number) 8 +(void()) __start() +(label) __start::@1 +(label) __start::@return +(label) __start::__init1 +(byte) conio_cursor_x loadstore zp[1]:6 5769.538461538461 +(byte) conio_cursor_y loadstore zp[1]:7 76190.64285714286 +(byte*) conio_line_color loadstore zp[2]:10 55250.175 +(byte*) conio_line_text loadstore zp[2]:8 53902.60975609756 +(void()) conio_mega65_init() +(label) conio_mega65_init::@return +(void()) cputc((byte) cputc::c) +(label) cputc::@1 +(label) cputc::@2 +(label) cputc::@3 +(label) cputc::@return +(byte) cputc::c +(byte) cputc::c#0 reg byte a 10501.5 +(void()) cputln() +(label) cputln::@return +(void()) cputs((to_nomodify byte*) cputs::s) +(label) cputs::@1 +(label) cputs::@2 +(label) cputs::@return +(byte) cputs::c +(byte) cputs::c#1 reg byte a 1001.0 +(to_nomodify byte*) cputs::s +(to_nomodify byte*) cputs::s#0 s zp[2]:2 500.5 +(to_nomodify byte*) cputs::s#2 s zp[2]:2 1501.5 +(void()) cscroll() +(label) cscroll::@1 +(label) cscroll::@2 +(label) cscroll::@3 +(label) cscroll::@4 +(label) cscroll::@5 +(label) cscroll::@return +(void()) main() +(label) main::@return +(const byte*) main::s[(byte) $d] = (byte*) "hello world!" +(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num) +(label) memcpy::@1 +(label) memcpy::@2 +(label) memcpy::@return +(void*) memcpy::destination +(void*) memcpy::destination#2 destination zp[2]:14 +(byte*) memcpy::dst +(byte*) memcpy::dst#1 dst zp[2]:14 1.000000001E9 +(byte*) memcpy::dst#2 dst zp[2]:14 1.0033333346666667E9 +(byte*) memcpy::dst#4 dst zp[2]:14 2.0000002E7 +(word) memcpy::num +(void*) memcpy::return +(void*) memcpy::source +(void*) memcpy::source#2 source zp[2]:4 +(byte*) memcpy::src +(byte*) memcpy::src#1 src zp[2]:4 2.000000002E9 +(byte*) memcpy::src#2 src zp[2]:4 1.00250000125E9 +(byte*) memcpy::src#4 src zp[2]:4 1.0000001E7 +(byte*) memcpy::src_end +(byte*) memcpy::src_end#0 src_end zp[2]:12 1.2625000025E8 +(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num) +(label) memset::@1 +(label) memset::@2 +(label) memset::@3 +(label) memset::@return +(byte) memset::c +(byte) memset::c#4 reg byte z 1.42857143E8 +(byte*) memset::dst +(byte*) memset::dst#1 dst zp[2]:4 2.000000002E9 +(byte*) memset::dst#2 dst zp[2]:4 1.3366666683333335E9 +(byte*) memset::dst#4 dst zp[2]:4 2.0000002E7 +(byte*) memset::end +(byte*) memset::end#0 end zp[2]:14 1.683333336666667E8 +(word) memset::num +(void*) memset::return +(void*) memset::str +(void*) memset::str#3 str zp[2]:4 +(const byte*) printf_buffer_number::digits[(number) $b] = { fill( $b, 0) } +(byte) printf_buffer_number::sign +(byte) printf_format_number::justify_left +(byte) printf_format_number::min_length +(byte) printf_format_number::radix +(byte) printf_format_number::sign_always +(byte) printf_format_number::upper_case +(byte) printf_format_number::zero_padding +(byte) printf_format_string::justify_left +(byte) printf_format_string::min_length + +zp[2]:2 [ cputs::s#2 cputs::s#0 ] +zp[2]:4 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +reg byte z [ memset::c#4 ] +zp[1]:6 [ conio_cursor_x ] +zp[1]:7 [ conio_cursor_y ] +zp[2]:8 [ conio_line_text ] +zp[2]:10 [ conio_line_color ] +reg byte a [ cputs::c#1 ] +reg byte a [ cputc::c#0 ] +zp[2]:12 [ memcpy::src_end#0 ] +zp[2]:14 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] + + +FINAL ASSEMBLER +Score: 8517 + + // File Comments +// Hello World for MEGA 65 - using stdio.h and conio.h +// Functions for performing input and output. + // Upstart +.cpu _45gs02 + .file [name="helloworld-mega65.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$2001] +.segmentdef Code [start=$2017] +.segmentdef Data [startAfter="Code"] +.segment Basic +.byte $0a, $20, $0a, $00, $fe, $02, $20, $30, $00 // 10 BANK 0 +.byte $15, $20, $14, $00, $9e, $20 // 20 SYS +.text toIntString(__start) // NNNN +.byte $00, $00, $00 // + // Global Constants & labels + // Map 2nd KB of colour RAM $DC00-$DFFF (hiding CIA's) + .const CRAM2K = 1 + .const LIGHT_BLUE = $e + // I/O Personality selection + .label IO_KEY = $d02f + // C65 Banking Register + .label IO_BANK = $d030 + // Color Ram + .label COLORRAM = $d800 + // Default address of screen character matrix + .label DEFAULT_SCREEN = $800 + // The number of bytes on the screen + // The current cursor x-position + .label conio_cursor_x = 6 + // The current cursor y-position + .label conio_cursor_y = 7 + // The current text cursor line start + .label conio_line_text = 8 + // The current color cursor line start + .label conio_line_color = $a +.segment Code + // __start +__start: { + // __start::__init1 + // conio_cursor_x = 0 + // [1] (byte) conio_cursor_x ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // conio_cursor_y = 0 + // [2] (byte) conio_cursor_y ← (byte) 0 -- vbuz1=vbuc1 + sta.z conio_cursor_y + // conio_line_text = CONIO_SCREEN_TEXT + // [3] (byte*) conio_line_text ← (const nomodify byte*) DEFAULT_SCREEN -- pbuz1=pbuc1 + lda #DEFAULT_SCREEN + sta.z conio_line_text+1 + // conio_line_color = CONIO_SCREEN_COLORS + // [4] (byte*) conio_line_color ← (const nomodify byte*) COLORRAM -- pbuz1=pbuc1 + lda #COLORRAM + sta.z conio_line_color+1 + // #pragma constructor_for(conio_mega65_init, cputc) + // [5] call conio_mega65_init + //#pragma constructor + jsr conio_mega65_init + // [6] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] + // __start::@1 + // [7] call main + // [15] phi from __start::@1 to main [phi:__start::@1->main] + jsr main + // __start::@return + // [8] return + rts +} + // conio_mega65_init +// Enable 2K Color ROM +conio_mega65_init: { + // asm + // asm { sei } + // Disable BASIC/KERNAL interrupts + sei + // asm { lda#0 tax tay taz map eom } + // Map memory to BANK 0 : 0x00XXXX - giving access to I/O + lda #0 + tax + tay + taz + map + eom + // *IO_KEY = 0x47 + // [11] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $47 -- _deref_pbuc1=vbuc2 + // Enable the VIC 4 + lda #$47 + sta IO_KEY + // *IO_KEY = 0x53 + // [12] *((const nomodify to_volatile byte*) IO_KEY) ← (byte) $53 -- _deref_pbuc1=vbuc2 + lda #$53 + sta IO_KEY + // *IO_BANK |= CRAM2K + // [13] *((const nomodify to_volatile byte*) IO_BANK) ← *((const nomodify to_volatile byte*) IO_BANK) | (const nomodify byte) CRAM2K -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // Enable 2K Color RAM + lda #CRAM2K + ora IO_BANK + sta IO_BANK + // conio_mega65_init::@return + // } + // [14] return + rts +} + // main +main: { + // printf("hello world!") + // [16] call cputs + // [18] phi from main to cputs [phi:main->cputs] + jsr cputs + // main::@return + // } + // [17] return + rts + .segment Data + s: .text "hello world!" + .byte 0 +} +.segment Code + // cputs +// Output a NUL-terminated string at the current cursor position +// cputs(byte* zp(2) s) +cputs: { + .label s = 2 + // [19] phi from cputs to cputs::@1 [phi:cputs->cputs::@1] + // [19] phi (to_nomodify byte*) cputs::s#2 = (const byte*) main::s [phi:cputs->cputs::@1#0] -- pbuz1=pbuc1 + lda #main.s + sta.z s+1 + // cputs::@1 + __b1: + // while(c=*s++) + // [20] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2) -- vbuaa=_deref_pbuz1 + ldy #0 + lda (s),y + // [21] (to_nomodify byte*) cputs::s#0 ← ++ (to_nomodify byte*) cputs::s#2 -- pbuz1=_inc_pbuz1 + inw.z s + // [22] if((byte) 0!=(byte) cputs::c#1) goto cputs::@2 -- vbuc1_neq_vbuaa_then_la1 + cmp #0 + bne __b2 + // cputs::@return + // } + // [23] return + rts + // cputs::@2 + __b2: + // cputc(c) + // [24] (byte) cputc::c#0 ← (byte) cputs::c#1 + // [25] call cputc + jsr cputc + // [19] phi from cputs::@2 to cputs::@1 [phi:cputs::@2->cputs::@1] + // [19] phi (to_nomodify byte*) cputs::s#2 = (to_nomodify byte*) cputs::s#0 [phi:cputs::@2->cputs::@1#0] -- register_copy + jmp __b1 +} + // cputc +// Output one character at the current cursor position +// Moves the cursor forward. Scrolls the entire screen if needed +// cputc(byte register(A) c) +cputc: { + // if(c=='\n') + // [26] if((byte) cputc::c#0==(byte) ' ') goto cputc::@1 -- vbuaa_eq_vbuc1_then_la1 + cmp #'\n' + beq __b1 + // cputc::@2 + // conio_line_text[conio_cursor_x] = c + // [27] *((byte*) conio_line_text + (byte) conio_cursor_x) ← (byte) cputc::c#0 -- pbuz1_derefidx_vbuz2=vbuaa + ldy.z conio_cursor_x + sta (conio_line_text),y + // conio_line_color[conio_cursor_x] = conio_textcolor + // [28] *((byte*) conio_line_color + (byte) conio_cursor_x) ← (const nomodify byte) LIGHT_BLUE -- pbuz1_derefidx_vbuz2=vbuc1 + lda #LIGHT_BLUE + sta (conio_line_color),y + // if(++conio_cursor_x==CONIO_WIDTH) + // [29] (byte) conio_cursor_x ← ++ (byte) conio_cursor_x -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_x + // [30] if((byte) conio_cursor_x!=(byte) $50) goto cputc::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$50 + cmp.z conio_cursor_x + bne __breturn + // [31] phi from cputc::@2 to cputc::@3 [phi:cputc::@2->cputc::@3] + // cputc::@3 + // cputln() + // [32] call cputln + jsr cputln + // cputc::@return + __breturn: + // } + // [33] return + rts + // [34] phi from cputc to cputc::@1 [phi:cputc->cputc::@1] + // cputc::@1 + __b1: + // cputln() + // [35] call cputln + jsr cputln + rts +} + // cputln +// Print a newline +cputln: { + // conio_line_text += CONIO_WIDTH + // [36] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $50 -- pbuz1=pbuz1_plus_vbuc1 + lda #$50 + clc + adc.z conio_line_text + sta.z conio_line_text + bcc !+ + inc.z conio_line_text+1 + !: + // conio_line_color += CONIO_WIDTH + // [37] (byte*) conio_line_color ← (byte*) conio_line_color + (byte) $50 -- pbuz1=pbuz1_plus_vbuc1 + lda #$50 + clc + adc.z conio_line_color + sta.z conio_line_color + bcc !+ + inc.z conio_line_color+1 + !: + // conio_cursor_x = 0 + // [38] (byte) conio_cursor_x ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z conio_cursor_x + // conio_cursor_y++; + // [39] (byte) conio_cursor_y ← ++ (byte) conio_cursor_y -- vbuz1=_inc_vbuz1 + inc.z conio_cursor_y + // cscroll() + // [40] call cscroll + jsr cscroll + // cputln::@return + // } + // [41] return + rts +} + // cscroll +// Scroll the entire screen if the cursor is beyond the last line +cscroll: { + // if(conio_cursor_y==CONIO_HEIGHT) + // [42] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return -- vbuz1_neq_vbuc1_then_la1 + lda #$19 + cmp.z conio_cursor_y + bne __breturn + // [43] phi from cscroll to cscroll::@1 [phi:cscroll->cscroll::@1] + // cscroll::@1 + // memcpy(CONIO_SCREEN_TEXT, CONIO_SCREEN_TEXT+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH) + // [44] call memcpy + // [55] phi from cscroll::@1 to memcpy [phi:cscroll::@1->memcpy] + // [55] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) DEFAULT_SCREEN [phi:cscroll::@1->memcpy#0] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN + sta.z memcpy.destination+1 + // [55] phi (void*) memcpy::source#2 = (void*)(const nomodify byte*) DEFAULT_SCREEN+(byte) $50 [phi:cscroll::@1->memcpy#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$50 + sta.z memcpy.source+1 + jsr memcpy + // [45] phi from cscroll::@1 to cscroll::@2 [phi:cscroll::@1->cscroll::@2] + // cscroll::@2 + // memcpy(CONIO_SCREEN_COLORS, CONIO_SCREEN_COLORS+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH) + // [46] call memcpy + // [55] phi from cscroll::@2 to memcpy [phi:cscroll::@2->memcpy] + // [55] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) COLORRAM [phi:cscroll::@2->memcpy#0] -- pvoz1=pvoc1 + lda #COLORRAM + sta.z memcpy.destination+1 + // [55] phi (void*) memcpy::source#2 = (void*)(const nomodify byte*) COLORRAM+(byte) $50 [phi:cscroll::@2->memcpy#1] -- pvoz1=pvoc1 + lda #COLORRAM+$50 + sta.z memcpy.source+1 + jsr memcpy + // [47] phi from cscroll::@2 to cscroll::@3 [phi:cscroll::@2->cscroll::@3] + // cscroll::@3 + // memset(CONIO_SCREEN_TEXT+CONIO_BYTES-CONIO_WIDTH, ' ', CONIO_WIDTH) + // [48] call memset + // [65] phi from cscroll::@3 to memset [phi:cscroll::@3->memset] + // [65] phi (byte) memset::c#4 = (byte) ' ' [phi:cscroll::@3->memset#0] -- vbuzz=vbuc1 + ldz #' ' + // [65] phi (void*) memset::str#3 = (void*)(const nomodify byte*) DEFAULT_SCREEN+(word)(number) $19*(number) $50-(byte) $50 [phi:cscroll::@3->memset#1] -- pvoz1=pvoc1 + lda #DEFAULT_SCREEN+$19*$50-$50 + sta.z memset.str+1 + jsr memset + // [49] phi from cscroll::@3 to cscroll::@4 [phi:cscroll::@3->cscroll::@4] + // cscroll::@4 + // memset(CONIO_SCREEN_COLORS+CONIO_BYTES-CONIO_WIDTH, conio_textcolor, CONIO_WIDTH) + // [50] call memset + // [65] phi from cscroll::@4 to memset [phi:cscroll::@4->memset] + // [65] phi (byte) memset::c#4 = (const nomodify byte) LIGHT_BLUE [phi:cscroll::@4->memset#0] -- vbuzz=vbuc1 + ldz #LIGHT_BLUE + // [65] phi (void*) memset::str#3 = (void*)(const nomodify byte*) COLORRAM+(word)(number) $19*(number) $50-(byte) $50 [phi:cscroll::@4->memset#1] -- pvoz1=pvoc1 + lda #COLORRAM+$19*$50-$50 + sta.z memset.str+1 + jsr memset + // cscroll::@5 + // conio_line_text -= CONIO_WIDTH + // [51] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $50 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_text + sbc #$50 + sta.z conio_line_text + lda.z conio_line_text+1 + sbc #0 + sta.z conio_line_text+1 + // conio_line_color -= CONIO_WIDTH + // [52] (byte*) conio_line_color ← (byte*) conio_line_color - (byte) $50 -- pbuz1=pbuz1_minus_vbuc1 + sec + lda.z conio_line_color + sbc #$50 + sta.z conio_line_color + lda.z conio_line_color+1 + sbc #0 + sta.z conio_line_color+1 + // conio_cursor_y--; + // [53] (byte) conio_cursor_y ← -- (byte) conio_cursor_y -- vbuz1=_dec_vbuz1 + dec.z conio_cursor_y + // cscroll::@return + __breturn: + // } + // [54] return + rts +} + // memcpy +// Copy block of memory (forwards) +// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. +// memcpy(void* zp($e) destination, void* zp(4) source) +memcpy: { + .label src_end = $c + .label dst = $e + .label src = 4 + .label source = 4 + .label destination = $e + // src_end = (char*)source+num + // [56] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word)(number) $19*(number) $50-(number) $50 -- pbuz1=pbuz2_plus_vwuc1 + lda.z source + clc + adc #<$19*$50-$50 + sta.z src_end + lda.z source+1 + adc #>$19*$50-$50 + sta.z src_end+1 + // [57] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 + // [58] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 + // [59] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1] + // [59] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy + // [59] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy + // memcpy::@1 + __b1: + // while(src!=src_end) + // [60] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 + lda.z src+1 + cmp.z src_end+1 + bne __b2 + lda.z src + cmp.z src_end + bne __b2 + // memcpy::@return + // } + // [61] return + rts + // memcpy::@2 + __b2: + // *dst++ = *src++ + // [62] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (src),y + sta (dst),y + // *dst++ = *src++; + // [63] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 + inw.z dst + // [64] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1 + inw.z src + jmp __b1 +} + // memset +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +// memset(void* zp(4) str, byte register(Z) c) +memset: { + .label end = $e + .label dst = 4 + .label str = 4 + // memset::@1 + // end = (char*)str + num + // [66] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (byte) $50 -- pbuz1=pbuz2_plus_vbuc1 + lda #$50 + clc + adc.z str + sta.z end + lda #0 + adc.z str+1 + sta.z end+1 + // [67] (byte*) memset::dst#4 ← (byte*)(void*) memset::str#3 + // [68] phi from memset::@1 memset::@3 to memset::@2 [phi:memset::@1/memset::@3->memset::@2] + // [68] phi (byte*) memset::dst#2 = (byte*) memset::dst#4 [phi:memset::@1/memset::@3->memset::@2#0] -- register_copy + // memset::@2 + __b2: + // for(char* dst = str; dst!=end; dst++) + // [69] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3 -- pbuz1_neq_pbuz2_then_la1 + lda.z dst+1 + cmp.z end+1 + bne __b3 + lda.z dst + cmp.z end + bne __b3 + // memset::@return + // } + // [70] return + rts + // memset::@3 + __b3: + // *dst = c + // [71] *((byte*) memset::dst#2) ← (byte) memset::c#4 -- _deref_pbuz1=vbuzz + tza + ldy #0 + sta (dst),y + // for(char* dst = str; dst!=end; dst++) + // [72] (byte*) memset::dst#1 ← ++ (byte*) memset::dst#2 -- pbuz1=_inc_pbuz1 + inw.z dst + jmp __b2 +} + // File Data + diff --git a/src/test/ref/examples/mega65/helloworld-mega65.sym b/src/test/ref/examples/mega65/helloworld-mega65.sym new file mode 100644 index 000000000..d17e7f4b8 --- /dev/null +++ b/src/test/ref/examples/mega65/helloworld-mega65.sym @@ -0,0 +1,191 @@ +(const nomodify byte*) COLORRAM = (byte*) 55296 +(const nomodify byte) CRAM2K = (byte) 1 +(const nomodify byte*) DEFAULT_SCREEN = (byte*) 2048 +(const nomodify to_volatile byte*) IO_BANK = (byte*) 53296 +(const nomodify to_volatile byte*) IO_KEY = (byte*) 53295 +(const nomodify byte) LIGHT_BLUE = (byte) $e +(byte) MOS6526_CIA::INTERRUPT +(byte) MOS6526_CIA::PORT_A +(byte) MOS6526_CIA::PORT_A_DDR +(byte) MOS6526_CIA::PORT_B +(byte) MOS6526_CIA::PORT_B_DDR +(byte) MOS6526_CIA::SERIAL_DATA +(word) MOS6526_CIA::TIMER_A +(byte) MOS6526_CIA::TIMER_A_CONTROL +(word) MOS6526_CIA::TIMER_B +(byte) MOS6526_CIA::TIMER_B_CONTROL +(byte) MOS6526_CIA::TOD_10THS +(byte) MOS6526_CIA::TOD_HOURS +(byte) MOS6526_CIA::TOD_MIN +(byte) MOS6526_CIA::TOD_SEC +(byte) MOS6569_VICII::BG_COLOR +(byte) MOS6569_VICII::BG_COLOR1 +(byte) MOS6569_VICII::BG_COLOR2 +(byte) MOS6569_VICII::BG_COLOR3 +(byte) MOS6569_VICII::BORDER_COLOR +(byte) MOS6569_VICII::CONTROL1 +(byte) MOS6569_VICII::CONTROL2 +(byte) MOS6569_VICII::IRQ_ENABLE +(byte) MOS6569_VICII::IRQ_STATUS +(byte) MOS6569_VICII::LIGHTPEN_X +(byte) MOS6569_VICII::LIGHTPEN_Y +(byte) MOS6569_VICII::MEMORY +(byte) MOS6569_VICII::RASTER +(byte) MOS6569_VICII::SPRITE0_COLOR +(byte) MOS6569_VICII::SPRITE0_X +(byte) MOS6569_VICII::SPRITE0_Y +(byte) MOS6569_VICII::SPRITE1_COLOR +(byte) MOS6569_VICII::SPRITE1_X +(byte) MOS6569_VICII::SPRITE1_Y +(byte) MOS6569_VICII::SPRITE2_COLOR +(byte) MOS6569_VICII::SPRITE2_X +(byte) MOS6569_VICII::SPRITE2_Y +(byte) MOS6569_VICII::SPRITE3_COLOR +(byte) MOS6569_VICII::SPRITE3_X +(byte) MOS6569_VICII::SPRITE3_Y +(byte) MOS6569_VICII::SPRITE4_COLOR +(byte) MOS6569_VICII::SPRITE4_X +(byte) MOS6569_VICII::SPRITE4_Y +(byte) MOS6569_VICII::SPRITE5_COLOR +(byte) MOS6569_VICII::SPRITE5_X +(byte) MOS6569_VICII::SPRITE5_Y +(byte) MOS6569_VICII::SPRITE6_COLOR +(byte) MOS6569_VICII::SPRITE6_X +(byte) MOS6569_VICII::SPRITE6_Y +(byte) MOS6569_VICII::SPRITE7_COLOR +(byte) MOS6569_VICII::SPRITE7_X +(byte) MOS6569_VICII::SPRITE7_Y +(byte) MOS6569_VICII::SPRITES_BG_COLLISION +(byte) MOS6569_VICII::SPRITES_COLLISION +(byte) MOS6569_VICII::SPRITES_ENABLE +(byte) MOS6569_VICII::SPRITES_EXPAND_X +(byte) MOS6569_VICII::SPRITES_EXPAND_Y +(byte) MOS6569_VICII::SPRITES_MC +(byte) MOS6569_VICII::SPRITES_MCOLOR1 +(byte) MOS6569_VICII::SPRITES_MCOLOR2 +(byte) MOS6569_VICII::SPRITES_PRIORITY +(byte) MOS6569_VICII::SPRITES_XMSB +(byte) MOS6581_SID::CH1_ATTACK_DECAY +(byte) MOS6581_SID::CH1_CONTROL +(word) MOS6581_SID::CH1_FREQ +(word) MOS6581_SID::CH1_PULSE_WIDTH +(byte) MOS6581_SID::CH1_SUSTAIN_RELEASE +(byte) MOS6581_SID::CH2_ATTACK_DECAY +(byte) MOS6581_SID::CH2_CONTROL +(word) MOS6581_SID::CH2_FREQ +(word) MOS6581_SID::CH2_PULSE_WIDTH +(byte) MOS6581_SID::CH2_SUSTAIN_RELEASE +(byte) MOS6581_SID::CH3_ATTACK_DECAY +(byte) MOS6581_SID::CH3_CONTROL +(byte) MOS6581_SID::CH3_ENV +(word) MOS6581_SID::CH3_FREQ +(byte) MOS6581_SID::CH3_OSC +(word) MOS6581_SID::CH3_PULSE_WIDTH +(byte) MOS6581_SID::CH3_SUSTAIN_RELEASE +(byte) MOS6581_SID::FILTER_CUTOFF_HIGH +(byte) MOS6581_SID::FILTER_CUTOFF_LOW +(byte) MOS6581_SID::FILTER_SETUP +(byte) MOS6581_SID::POT_X +(byte) MOS6581_SID::POT_Y +(byte) MOS6581_SID::VOLUME_FILTER_MODE +(const byte) RADIX::BINARY = (number) 2 +(const byte) RADIX::DECIMAL = (number) $a +(const byte) RADIX::HEXADECIMAL = (number) $10 +(const byte) RADIX::OCTAL = (number) 8 +(void()) __start() +(label) __start::@1 +(label) __start::@return +(label) __start::__init1 +(byte) conio_cursor_x loadstore zp[1]:6 5769.538461538461 +(byte) conio_cursor_y loadstore zp[1]:7 76190.64285714286 +(byte*) conio_line_color loadstore zp[2]:10 55250.175 +(byte*) conio_line_text loadstore zp[2]:8 53902.60975609756 +(void()) conio_mega65_init() +(label) conio_mega65_init::@return +(void()) cputc((byte) cputc::c) +(label) cputc::@1 +(label) cputc::@2 +(label) cputc::@3 +(label) cputc::@return +(byte) cputc::c +(byte) cputc::c#0 reg byte a 10501.5 +(void()) cputln() +(label) cputln::@return +(void()) cputs((to_nomodify byte*) cputs::s) +(label) cputs::@1 +(label) cputs::@2 +(label) cputs::@return +(byte) cputs::c +(byte) cputs::c#1 reg byte a 1001.0 +(to_nomodify byte*) cputs::s +(to_nomodify byte*) cputs::s#0 s zp[2]:2 500.5 +(to_nomodify byte*) cputs::s#2 s zp[2]:2 1501.5 +(void()) cscroll() +(label) cscroll::@1 +(label) cscroll::@2 +(label) cscroll::@3 +(label) cscroll::@4 +(label) cscroll::@5 +(label) cscroll::@return +(void()) main() +(label) main::@return +(const byte*) main::s[(byte) $d] = (byte*) "hello world!" +(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num) +(label) memcpy::@1 +(label) memcpy::@2 +(label) memcpy::@return +(void*) memcpy::destination +(void*) memcpy::destination#2 destination zp[2]:14 +(byte*) memcpy::dst +(byte*) memcpy::dst#1 dst zp[2]:14 1.000000001E9 +(byte*) memcpy::dst#2 dst zp[2]:14 1.0033333346666667E9 +(byte*) memcpy::dst#4 dst zp[2]:14 2.0000002E7 +(word) memcpy::num +(void*) memcpy::return +(void*) memcpy::source +(void*) memcpy::source#2 source zp[2]:4 +(byte*) memcpy::src +(byte*) memcpy::src#1 src zp[2]:4 2.000000002E9 +(byte*) memcpy::src#2 src zp[2]:4 1.00250000125E9 +(byte*) memcpy::src#4 src zp[2]:4 1.0000001E7 +(byte*) memcpy::src_end +(byte*) memcpy::src_end#0 src_end zp[2]:12 1.2625000025E8 +(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num) +(label) memset::@1 +(label) memset::@2 +(label) memset::@3 +(label) memset::@return +(byte) memset::c +(byte) memset::c#4 reg byte z 1.42857143E8 +(byte*) memset::dst +(byte*) memset::dst#1 dst zp[2]:4 2.000000002E9 +(byte*) memset::dst#2 dst zp[2]:4 1.3366666683333335E9 +(byte*) memset::dst#4 dst zp[2]:4 2.0000002E7 +(byte*) memset::end +(byte*) memset::end#0 end zp[2]:14 1.683333336666667E8 +(word) memset::num +(void*) memset::return +(void*) memset::str +(void*) memset::str#3 str zp[2]:4 +(const byte*) printf_buffer_number::digits[(number) $b] = { fill( $b, 0) } +(byte) printf_buffer_number::sign +(byte) printf_format_number::justify_left +(byte) printf_format_number::min_length +(byte) printf_format_number::radix +(byte) printf_format_number::sign_always +(byte) printf_format_number::upper_case +(byte) printf_format_number::zero_padding +(byte) printf_format_string::justify_left +(byte) printf_format_string::min_length + +zp[2]:2 [ cputs::s#2 cputs::s#0 ] +zp[2]:4 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] +reg byte z [ memset::c#4 ] +zp[1]:6 [ conio_cursor_x ] +zp[1]:7 [ conio_cursor_y ] +zp[2]:8 [ conio_line_text ] +zp[2]:10 [ conio_line_color ] +reg byte a [ cputs::c#1 ] +reg byte a [ cputc::c#0 ] +zp[2]:12 [ memcpy::src_end#0 ] +zp[2]:14 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]