1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-22 16:33:48 +00:00

Now initializing cursor position in conio.h on MEGA65. Closes #522

This commit is contained in:
jespergravgaard 2020-09-28 21:34:39 +02:00
parent c75c99654b
commit 8ec4831541
5 changed files with 1401 additions and 602 deletions

View File

@ -44,6 +44,11 @@ void conio_mega65_init() {
*IO_KEY = 0x53;
// Enable 2K Color RAM
*IO_BANK |= CRAM2K;
// Position cursor at current line
char * const BASIC_CURSOR_LINE = 0xeb;
char line = *BASIC_CURSOR_LINE+1;
if(line>24) line=24;
gotoxy(0, line);
}
// Return true if there's a key waiting, return false if not

View File

@ -56,6 +56,8 @@ __start: {
}
// Enable 2K Color ROM
conio_mega65_init: {
// Position cursor at current line
.label BASIC_CURSOR_LINE = $eb
// asm
// Disable BASIC/KERNAL interrupts
sei
@ -78,6 +80,16 @@ conio_mega65_init: {
lda #CRAM2K
ora IO_BANK
sta IO_BANK
// line = *BASIC_CURSOR_LINE+1
ldx BASIC_CURSOR_LINE
inx
// if(line>24)
cpx #$18+1
bcc __b1
ldx #$18
__b1:
// gotoxy(0, line)
jsr gotoxy
// }
rts
}
@ -91,6 +103,80 @@ main: {
.byte 0
}
.segment Code
// Set the cursor to the specified position
// gotoxy(byte register(X) y)
gotoxy: {
.const x = 0
.label __5 = $10
.label __6 = $c
.label __7 = $c
.label line_offset = $c
.label __8 = $e
.label __9 = $c
// if(y>CONIO_HEIGHT)
cpx #$19+1
bcc __b2
ldx #0
__b2:
// conio_cursor_x = x
lda #x
sta.z conio_cursor_x
// conio_cursor_y = y
stx.z conio_cursor_y
// (unsigned int)y*CONIO_WIDTH
txa
sta.z __7
lda #0
sta.z __7+1
// line_offset = (unsigned int)y*CONIO_WIDTH
lda.z __7
asl
sta.z __8
lda.z __7+1
rol
sta.z __8+1
asl.z __8
rol.z __8+1
lda.z __9
clc
adc.z __8
sta.z __9
lda.z __9+1
adc.z __8+1
sta.z __9+1
asw line_offset
asw line_offset
asw line_offset
asw line_offset
// CONIO_SCREEN_TEXT + line_offset
lda.z line_offset
clc
adc #<DEFAULT_SCREEN
sta.z __5
lda.z line_offset+1
adc #>DEFAULT_SCREEN
sta.z __5+1
// conio_line_text = CONIO_SCREEN_TEXT + line_offset
lda.z __5
sta.z conio_line_text
lda.z __5+1
sta.z conio_line_text+1
// CONIO_SCREEN_COLORS + line_offset
clc
lda.z __6
adc #<COLORRAM
sta.z __6
lda.z __6+1
adc #>COLORRAM
sta.z __6+1
// conio_line_color = CONIO_SCREEN_COLORS + line_offset
lda.z __6
sta.z conio_line_color
lda.z __6+1
sta.z conio_line_color+1
// }
rts
}
// Output a NUL-terminated string at the current cursor position
// cputs(byte* zp(2) s)
cputs: {
@ -233,13 +319,13 @@ cscroll: {
}
// 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(void* zp($14) destination, void* zp(4) source)
memcpy: {
.label src_end = $c
.label dst = $e
.label src_end = $12
.label dst = $14
.label src = 4
.label source = 4
.label destination = $e
.label destination = $14
// src_end = (char*)source+num
lda.z source
clc
@ -271,7 +357,7 @@ memcpy: {
// 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 end = $14
.label dst = 4
.label str = 4
// end = (char*)str + num

View File

@ -25,141 +25,177 @@ conio_mega65_init: scope:[conio_mega65_init] from __start::__init1
[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
[14] (byte) conio_mega65_init::line#0 ← *((const nomodify byte*) conio_mega65_init::BASIC_CURSOR_LINE) + (byte) 1
[15] if((byte) conio_mega65_init::line#0<(byte) $18+(byte) 1) goto conio_mega65_init::@2
to:conio_mega65_init::@1
conio_mega65_init::@2: scope:[conio_mega65_init] from conio_mega65_init
[16] phi()
to:conio_mega65_init::@1
conio_mega65_init::@1: scope:[conio_mega65_init] from conio_mega65_init conio_mega65_init::@2
[17] (byte) conio_mega65_init::line#2 ← phi( conio_mega65_init::@2/(byte) conio_mega65_init::line#0 conio_mega65_init/(byte) $18 )
[18] (byte) gotoxy::y#2 ← (byte) conio_mega65_init::line#2
[19] call gotoxy
to:conio_mega65_init::@return
conio_mega65_init::@return: scope:[conio_mega65_init] from conio_mega65_init
[14] return
conio_mega65_init::@return: scope:[conio_mega65_init] from conio_mega65_init::@1
[20] return
to:@return
(void()) main()
main: scope:[main] from __start::@1
[15] phi()
[16] call cputs
[21] phi()
[22] call cputs
to:main::@return
main::@return: scope:[main] from main
[17] return
[23] return
to:@return
(void()) gotoxy((byte) gotoxy::x , (byte) gotoxy::y)
gotoxy: scope:[gotoxy] from conio_mega65_init::@1
[24] if((byte) gotoxy::y#2<(byte) $19+(byte) 1) goto gotoxy::@3
to:gotoxy::@1
gotoxy::@3: scope:[gotoxy] from gotoxy
[25] phi()
to:gotoxy::@1
gotoxy::@1: scope:[gotoxy] from gotoxy gotoxy::@3
[26] (byte) gotoxy::y#4 ← phi( gotoxy::@3/(byte) gotoxy::y#2 gotoxy/(byte) 0 )
to:gotoxy::@2
gotoxy::@2: scope:[gotoxy] from gotoxy::@1
[27] (byte) conio_cursor_x ← (const byte) gotoxy::x#2
[28] (byte) conio_cursor_y ← (byte) gotoxy::y#4
[29] (word~) gotoxy::$7 ← (word)(byte) gotoxy::y#4
[30] (word~) gotoxy::$8 ← (word~) gotoxy::$7 << (byte) 2
[31] (word~) gotoxy::$9 ← (word~) gotoxy::$8 + (word~) gotoxy::$7
[32] (word) gotoxy::line_offset#0 ← (word~) gotoxy::$9 << (byte) 4
[33] (byte*~) gotoxy::$5 ← (const nomodify byte*) DEFAULT_SCREEN + (word) gotoxy::line_offset#0
[34] (byte*) conio_line_text ← (byte*~) gotoxy::$5
[35] (byte*~) gotoxy::$6 ← (const nomodify byte*) COLORRAM + (word) gotoxy::line_offset#0
[36] (byte*) conio_line_color ← (byte*~) gotoxy::$6
to:gotoxy::@return
gotoxy::@return: scope:[gotoxy] from gotoxy::@2
[37] return
to:@return
(void()) cputs((to_nomodify byte*) cputs::s)
cputs: scope:[cputs] from main
[18] phi()
[38] 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
[39] (to_nomodify byte*) cputs::s#2 ← phi( cputs/(const byte*) main::s cputs::@2/(to_nomodify byte*) cputs::s#0 )
[40] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2)
[41] (to_nomodify byte*) cputs::s#0 ← ++ (to_nomodify byte*) cputs::s#2
[42] if((byte) 0!=(byte) cputs::c#1) goto cputs::@2
to:cputs::@return
cputs::@return: scope:[cputs] from cputs::@1
[23] return
[43] return
to:@return
cputs::@2: scope:[cputs] from cputs::@1
[24] (byte) cputc::c#0 ← (byte) cputs::c#1
[25] call cputc
[44] (byte) cputc::c#0 ← (byte) cputs::c#1
[45] call cputc
to:cputs::@1
(void()) cputc((byte) cputc::c)
cputc: scope:[cputc] from cputs::@2
[26] if((byte) cputc::c#0==(byte) '
[46] 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
[47] *((byte*) conio_line_text + (byte) conio_cursor_x) ← (byte) cputc::c#0
[48] *((byte*) conio_line_color + (byte) conio_cursor_x) ← (const nomodify byte) LIGHT_BLUE
[49] (byte) conio_cursor_x ← ++ (byte) conio_cursor_x
[50] 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
[51] phi()
[52] call cputln
to:cputc::@return
cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@3
[33] return
[53] return
to:@return
cputc::@1: scope:[cputc] from cputc
[34] phi()
[35] call cputln
[54] phi()
[55] 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
[56] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $50
[57] (byte*) conio_line_color ← (byte*) conio_line_color + (byte) $50
[58] (byte) conio_cursor_x ← (byte) 0
[59] (byte) conio_cursor_y ← ++ (byte) conio_cursor_y
[60] call cscroll
to:cputln::@return
cputln::@return: scope:[cputln] from cputln
[41] return
[61] return
to:@return
(void()) cscroll()
cscroll: scope:[cscroll] from cputln
[42] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return
[62] if((byte) conio_cursor_y!=(byte) $19) goto cscroll::@return
to:cscroll::@1
cscroll::@1: scope:[cscroll] from cscroll
[43] phi()
[44] call memcpy
[63] phi()
[64] call memcpy
to:cscroll::@2
cscroll::@2: scope:[cscroll] from cscroll::@1
[45] phi()
[46] call memcpy
[65] phi()
[66] call memcpy
to:cscroll::@3
cscroll::@3: scope:[cscroll] from cscroll::@2
[47] phi()
[48] call memset
[67] phi()
[68] call memset
to:cscroll::@4
cscroll::@4: scope:[cscroll] from cscroll::@3
[49] phi()
[50] call memset
[69] phi()
[70] 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
[71] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $50
[72] (byte*) conio_line_color ← (byte*) conio_line_color - (byte) $50
[73] (byte) conio_cursor_y ← -- (byte) conio_cursor_y
to:cscroll::@return
cscroll::@return: scope:[cscroll] from cscroll cscroll::@5
[54] return
[74] 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
[75] (void*) memcpy::destination#2 ← phi( cscroll::@1/(void*)(const nomodify byte*) DEFAULT_SCREEN cscroll::@2/(void*)(const nomodify byte*) COLORRAM )
[75] (void*) memcpy::source#2 ← phi( cscroll::@1/(void*)(const nomodify byte*) DEFAULT_SCREEN+(byte) $50 cscroll::@2/(void*)(const nomodify byte*) COLORRAM+(byte) $50 )
[76] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word)(number) $19*(number) $50-(number) $50
[77] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
[78] (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
[79] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#4 memcpy::@2/(byte*) memcpy::dst#1 )
[79] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#4 memcpy::@2/(byte*) memcpy::src#1 )
[80] 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
[81] 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
[82] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
[83] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
[84] (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 )
[85] (byte) memset::c#4 ← phi( cscroll::@3/(byte) ' ' cscroll::@4/(const nomodify byte) LIGHT_BLUE )
[85] (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
[86] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (byte) $50
[87] (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
[88] (byte*) memset::dst#2 ← phi( memset::@1/(byte*) memset::dst#4 memset::@3/(byte*) memset::dst#1 )
[89] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3
to:memset::@return
memset::@return: scope:[memset] from memset::@2
[70] return
[90] 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
[91] *((byte*) memset::dst#2) ← (byte) memset::c#4
[92] (byte*) memset::dst#1 ← ++ (byte*) memset::dst#2
to:memset::@2

File diff suppressed because it is too large Load Diff

View File

@ -321,12 +321,18 @@
(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
(byte) conio_cursor_x loadstore zp[1]:6 4288.828571428571
(byte) conio_cursor_y loadstore zp[1]:7 62747.2156862745
(byte*) conio_line_color loadstore zp[2]:10 51397.860465116275
(byte*) conio_line_text loadstore zp[2]:8 49113.51111111111
(void()) conio_mega65_init()
(label) conio_mega65_init::@1
(label) conio_mega65_init::@2
(label) conio_mega65_init::@return
(const nomodify byte*) conio_mega65_init::BASIC_CURSOR_LINE = (byte*) 235
(byte) conio_mega65_init::line
(byte) conio_mega65_init::line#0 reg byte x 11.0
(byte) conio_mega65_init::line#2 reg byte x 22.0
(void()) cputc((byte) cputc::c)
(label) cputc::@1
(label) cputc::@2
@ -352,6 +358,23 @@
(label) cscroll::@4
(label) cscroll::@5
(label) cscroll::@return
(void()) gotoxy((byte) gotoxy::x , (byte) gotoxy::y)
(byte*~) gotoxy::$5 zp[2]:16 202.0
(byte*~) gotoxy::$6 zp[2]:12 202.0
(word~) gotoxy::$7 zp[2]:12 151.5
(word~) gotoxy::$8 zp[2]:14 202.0
(word~) gotoxy::$9 zp[2]:12 202.0
(label) gotoxy::@1
(label) gotoxy::@2
(label) gotoxy::@3
(label) gotoxy::@return
(word) gotoxy::line_offset
(word) gotoxy::line_offset#0 line_offset zp[2]:12 101.0
(byte) gotoxy::x
(const byte) gotoxy::x#2 x = (byte) 0
(byte) gotoxy::y
(byte) gotoxy::y#2 reg byte x 71.0
(byte) gotoxy::y#4 reg byte x 67.33333333333333
(void()) main()
(label) main::@return
(const byte*) main::s[(byte) $d] = (byte*) "hello world!"
@ -360,11 +383,11 @@
(label) memcpy::@2
(label) memcpy::@return
(void*) memcpy::destination
(void*) memcpy::destination#2 destination zp[2]:14
(void*) memcpy::destination#2 destination zp[2]:20
(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
(byte*) memcpy::dst#1 dst zp[2]:20 1.000000001E9
(byte*) memcpy::dst#2 dst zp[2]:20 1.0033333346666667E9
(byte*) memcpy::dst#4 dst zp[2]:20 2.0000002E7
(word) memcpy::num
(void*) memcpy::return
(void*) memcpy::source
@ -374,7 +397,7 @@
(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
(byte*) memcpy::src_end#0 src_end zp[2]:18 1.2625000025E8
(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num)
(label) memset::@1
(label) memset::@2
@ -387,7 +410,7 @@
(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
(byte*) memset::end#0 end zp[2]:20 1.683333336666667E8
(word) memset::num
(void*) memset::return
(void*) memset::str
@ -403,6 +426,8 @@
(byte) printf_format_string::justify_left
(byte) printf_format_string::min_length
reg byte x [ conio_mega65_init::line#2 conio_mega65_init::line#0 ]
reg byte x [ gotoxy::y#4 gotoxy::y#2 ]
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 ]
@ -410,7 +435,10 @@ zp[1]:6 [ conio_cursor_x ]
zp[1]:7 [ conio_cursor_y ]
zp[2]:8 [ conio_line_text ]
zp[2]:10 [ conio_line_color ]
zp[2]:12 [ gotoxy::$7 gotoxy::$9 gotoxy::line_offset#0 gotoxy::$6 ]
zp[2]:14 [ gotoxy::$8 ]
zp[2]:16 [ gotoxy::$5 ]
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 ]
zp[2]:18 [ memcpy::src_end#0 ]
zp[2]:20 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]