added memcopy function

This commit is contained in:
Irmen de Jong 2019-01-01 18:38:43 +01:00
parent ac8e7f4fa9
commit c2eb181b5a
8 changed files with 55 additions and 14 deletions

View File

@ -35,13 +35,7 @@
c64.STROUT("balloon sprites!\n")
c64.STROUT("...we are all floating...\n")
; copy the ballon sprite data to the correct address and setup the sprite pointers
; @todo make a memcopy function for this, that calls c64utils.memcopy
for ubyte i in 0 to 63 {
;@(sprite_data_address+i) = @(balloonsprite+i) ; @todo nice error message
@(sprite_data_address+i) = balloonsprite[i]
}
memcopy(balloonsprite, sprite_data_address, 63)
c64.SPRPTR0 = sprite_data_address//64
c64.SPRPTR1 = sprite_data_address//64
c64.SPRPTR2 = sprite_data_address//64
@ -59,11 +53,6 @@
c64.SPENA = 255 ; enable all sprites
set_irqvec() ; enable animation
;set_irqvec_excl() ; enable animation
}
sub foobar() {
A=99
}
}

View File

@ -1,6 +1,7 @@
%import c64utils
~ main {
ubyte[3] balloonsprite = [ %00000000,%01111111,%00000000 ]
sub start() {
ubyte i=0
@ -13,5 +14,8 @@
@($d020) = @($d020+i) + 1
@($d020+i) = @($d020+i) + 1
c64scr.print_ub(X)
i = 2+balloonsprite
}
}

View File

@ -851,7 +851,13 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
val leftDt = left.resultingDatatype(namespace, heap)
val rightDt = right.resultingDatatype(namespace, heap)
return when(operator) {
"+", "-", "*", "**", "%" -> if(leftDt==null || rightDt==null) null else arithmeticOpDt(leftDt, rightDt)
"+", "-", "*", "**", "%" -> if(leftDt==null || rightDt==null) null else {
try {
arithmeticOpDt(leftDt, rightDt)
} catch(x: FatalAstException) {
null
}
}
"//" -> if(leftDt==null || rightDt==null) null else integerDivisionOpDt(leftDt, rightDt)
"&" -> leftDt
"|" -> leftDt

View File

@ -696,6 +696,13 @@ class AstChecker(private val namespace: INameScope,
}
}
}
val leftDt = expr.left.resultingDatatype(namespace, heap)!!
val rightDt = expr.right.resultingDatatype(namespace, heap)!!
if(leftDt !in NumericDatatypes)
checkResult.add(ExpressionError("left operand is not numeric", expr.left.position))
if(rightDt!in NumericDatatypes)
checkResult.add(ExpressionError("right operand is not numeric", expr.right.position))
return super.process(expr)
}

View File

@ -57,6 +57,10 @@ val BuiltinFunctions = mapOf(
"set_irqvec" to FunctionSignature(false, emptyList(), null),
"set_irqvec_excl" to FunctionSignature(false, emptyList(), null),
"restore_irqvec" to FunctionSignature(false, emptyList(), null),
"memcopy" to FunctionSignature(false, listOf(
BuiltinFunctionParam("from", IntegerDatatypes + IterableDatatypes),
BuiltinFunctionParam("to", IntegerDatatypes + IterableDatatypes),
BuiltinFunctionParam("numbytes", IntegerDatatypes)), null),
"vm_write_memchr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", setOf(DataType.UWORD))), null),
"vm_write_memstr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", setOf(DataType.UWORD))), null),
"vm_write_num" to FunctionSignature(false, listOf(BuiltinFunctionParam("number", NumericDatatypes)), null),

View File

@ -72,7 +72,8 @@ enum class Syscall(val callNr: Short) {
FUNC_SUM_F(134),
FUNC_SET_IRQVEC(135),
FUNC_SET_IRQVEC_EXCL(136),
FUNC_RESTORE_IRQVEC(137)
FUNC_RESTORE_IRQVEC(137),
FUNC_MEMCOPY(138)
// note: not all builtin functions of the Prog8 language are present as functions:
// some of them are straight opcodes (such as MSB, LSB, LSL, LSR, ROL_BYTE, ROR, ROL2, ROR2, and FLT)!
@ -1614,6 +1615,7 @@ class StackVm(private var traceOutputFile: String?) {
}
Syscall.FUNC_SET_IRQVEC, Syscall.FUNC_SET_IRQVEC_EXCL -> TODO()
Syscall.FUNC_RESTORE_IRQVEC -> TODO()
Syscall.FUNC_MEMCOPY -> TODO()
}
}

View File

@ -618,6 +618,13 @@ ror2(x)
It uses some extra logic to not consider the carry flag as extra rotation bit.
Modifies in-place, doesn't return a value (so can't be used in an expression).
memcopy(from, to, numbytes)
Efficiently copy a number of bytes (1 - 256) from a memory location to another.
NOTE: 'to' must NOT overlap with 'from', unless it is *before* 'from'.
Because this function imposes some overhead to handle the parameters,
it is only faster if the number of bytes is larger than a certain threshold.
Compare the generated code to see if it was beneficial or not.
set_carry() / clear_carry()
Set (or clear) the CPU status register Carry flag. No result value.
(translated into ``SEC`` or ``CLC`` cpu instruction)

View File

@ -1589,6 +1589,28 @@ func_rndf .proc
_rndf_rnum5 .byte 0,0,0,0,0
.pend
func_memcopy .proc ; clobbers A,Y
inx
stx SCRATCH_ZPREGX
lda ESTACK_LO+2,x
sta SCRATCH_ZPWORD1
lda ESTACK_HI+2,x
sta SCRATCH_ZPWORD1+1
lda ESTACK_HI+1,x
tay
lda ESTACK_LO+1,x
pha
lda ESTACK_LO,x
tax
pla
jsr c64utils.memcopy
ldx SCRATCH_ZPREGX
inx
inx
rts
.pend
}}
}