diff --git a/compiler/res/prog8lib/virtual/string.p8 b/compiler/res/prog8lib/virtual/string.p8 index 2be984467..6f01b08fd 100644 --- a/compiler/res/prog8lib/virtual/string.p8 +++ b/compiler/res/prog8lib/virtual/string.p8 @@ -79,14 +79,12 @@ string { ; Returns the length of the string that was copied. ; Often you don’t have to call this explicitly and can just write string1 = string2 ; but this function is useful if you’re dealing with addresses for instance. - ubyte ix - repeat { - ubyte char=source[ix] - target[ix]=char - if not char - return ix - ix++ - } + %ir {{ + loadm.w r65534,string.copy.source + loadm.w r65535,string.copy.target + syscall 52 (r65534.w, r65535.w): r0.b + returnr.b r0 + }} } sub append(str target, str suffix) -> ubyte { diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index c197042d2..257884240 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -31,34 +31,38 @@ sys { sub internal_stringcopy(uword source, uword tgt) { ; Called when the compiler wants to assign a string value to another string. - while @(source) { - @(tgt) = @(source) - source++ - tgt++ - } - @(tgt)=0 + %ir {{ + loadm.w r65534,sys.internal_stringcopy.source + loadm.w r65535,sys.internal_stringcopy.tgt + syscall 52 (r65534.w, r65535.w): r0.b + }} } sub memcopy(uword source, uword tgt, uword count) { - repeat count { - @(tgt) = @(source) - source++ - tgt++ - } + %ir {{ + loadm.w r65533,sys.memcopy.source + loadm.w r65534,sys.memcopy.tgt + loadm.w r65535,sys.memcopy.count + syscall 49 (r65533.w, r65534.w, r65535.w) + }} } sub memset(uword mem, uword numbytes, ubyte value) { - repeat numbytes { - @(mem) = value - mem++ - } + %ir {{ + loadm.w r65533,sys.memset.mem + loadm.w r65534,sys.memset.numbytes + loadm.b r65535,sys.memset.value + syscall 50 (r65533.w, r65534.w, r65535.b) + }} } sub memsetw(uword mem, uword numwords, uword value) { - repeat numwords { - pokew(mem, value) - mem+=2 - } + %ir {{ + loadm.w r65533,sys.memsetw.mem + loadm.w r65534,sys.memsetw.numwords + loadm.w r65535,sys.memsetw.value + syscall 51 (r65533.w, r65534.w, r65535.w) + }} } sub exit(ubyte returnvalue) { diff --git a/examples/test.p8 b/examples/test.p8 index b69458724..c57c57d51 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -6,24 +6,41 @@ main { sub start() { - ubyte x - ubyte y - uword bytes = $a000 + str name1 = "irmen de jong\n" + str name2 = "123456" + sys.memcopy(&name2, &name1+5,len(name2)) + txt.print(name1) + sys.memset(&name1+3, 8, '!') + txt.print(name1) + sys.memsetw(&name1+3, 4, $5544) + txt.print(name1) + name1 = name2 + txt.print(name1) + txt.nl() + ubyte length = string.copy("hello there", name1) + txt.print_ub(length) + txt.spc() + txt.print(name1) + txt.nl() - for y in 0 to 59 { - for x in 0 to 79 { - txt.setchr(x, y, @(bytes+$1000)) - bytes++ - } - } - } - - sub stringcopy() { - str name1 = "name1" - str name2 = "name2" - uword[] @split names = [name1, name2, "name3"] - uword[] addresses = [0,0,0] - names = [1111,2222,3333] - addresses = names +; str name1 = "name1" +; str name2 = "name2" +; uword[] @split names = [name1, name2, "name3"] +; uword[] addresses = [0,0,0] +; names = [1111,2222,3333] +; +; for cx16.r0 in names { +; txt.print_uw(cx16.r0) +; txt.spc() +; } +; txt.nl() +; +; addresses = names +; +; for cx16.r0 in addresses { +; txt.print_uw(cx16.r0) +; txt.spc() +; } +; txt.nl() } } diff --git a/virtualmachine/src/prog8/vm/SysCalls.kt b/virtualmachine/src/prog8/vm/SysCalls.kt index 447dfa058..f287a1729 100644 --- a/virtualmachine/src/prog8/vm/SysCalls.kt +++ b/virtualmachine/src/prog8/vm/SysCalls.kt @@ -56,6 +56,10 @@ SYSCALLS: 46 = MUL16_LAST_UPPER 47 = float to str 48 = FLOATARRAY_CONTAINS +49 = memcopy +50 = memset +51 = memsetw +52 = stringcopy */ enum class Syscall { @@ -108,6 +112,10 @@ enum class Syscall { MUL16_LAST_UPPER, FLOAT_TO_STR, FLOATARRAY_CONTAINS, + MEMCOPY, + MEMSET, + MEMSETW, + STRINGCOPY, ; companion object { @@ -532,6 +540,41 @@ object SysCalls { val numStr = if(numf.toInt().toDouble()==numf) numf.toInt().toString() else numf.toString() vm.memory.setString(bufferAddr, numStr, true) } + Syscall.MEMCOPY -> { + val (fromA, toA, countA) = getArgValues(callspec.arguments, vm) + val from = (fromA as UShort).toInt() + val to = (toA as UShort).toInt() + val count = (countA as UShort).toInt() + for(offset in 0.. { + val (memA, numbytesA, valueA) = getArgValues(callspec.arguments, vm) + val mem = (memA as UShort).toInt() + val numbytes = (numbytesA as UShort).toInt() + val value = valueA as UByte + for(addr in mem.. { + val (memA, numwordsA, valueA) = getArgValues(callspec.arguments, vm) + val mem = (memA as UShort).toInt() + val numwords = (numwordsA as UShort).toInt() + val value = valueA as UShort + for(addr in mem.. { + val (sourceA, targetA) = getArgValues(callspec.arguments, vm) + val source = (sourceA as UShort).toInt() + val target = (targetA as UShort).toInt() + val string = vm.memory.getString(source) + vm.memory.setString(target, string, true) + returnValue(callspec.returns!!, string.length, vm) + } } } }