diff --git a/compiler/res/prog8lib/prog8lib.asm b/compiler/res/prog8lib/prog8lib.asm index 8432809ad..6eb893f35 100644 --- a/compiler/res/prog8lib/prog8lib.asm +++ b/compiler/res/prog8lib/prog8lib.asm @@ -105,6 +105,99 @@ not_word .proc sta c64.ESTACK_HI + 1,x rts .pend + + +and_b .proc + ; -- logical and (of 2 bytes) + lda c64.ESTACK_LO+2,x + beq + + lda #1 ++ sta c64.SCRATCH_ZPB1 + lda c64.ESTACK_LO+1,x + beq + + lda #1 ++ and c64.SCRATCH_ZPB1 + inx + sta c64.ESTACK_LO+1,x + rts + .pend + +or_b .proc + ; -- logical or (of 2 bytes) + lda c64.ESTACK_LO+2,x + ora c64.ESTACK_LO+1,x + beq + + lda #1 ++ inx + sta c64.ESTACK_LO+1,x + rts + .pend + +xor_b .proc + ; -- logical xor (of 2 bytes) + lda c64.ESTACK_LO+2,x + beq + + lda #1 ++ sta c64.SCRATCH_ZPB1 + lda c64.ESTACK_LO+1,x + beq + + lda #1 ++ eor c64.SCRATCH_ZPB1 + inx + sta c64.ESTACK_LO+1,x + rts + .pend + +and_w .proc + ; -- logical and (word and word -> byte) + lda c64.ESTACK_LO+2,x + ora c64.ESTACK_HI+2,x + beq + + lda #1 ++ sta c64.SCRATCH_ZPB1 + lda c64.ESTACK_LO+1,x + ora c64.ESTACK_HI+1,x + beq + + lda #1 ++ and c64.SCRATCH_ZPB1 + inx + sta c64.ESTACK_LO+1,x + sta c64.ESTACK_HI+1,x + rts + .pend + +or_w .proc + ; -- logical or (word or word -> byte) + lda c64.ESTACK_LO+2,x + ora c64.ESTACK_LO+1,x + ora c64.ESTACK_HI+2,x + ora c64.ESTACK_HI+1,x + beq + + lda #1 ++ inx + sta c64.ESTACK_LO+1,x + sta c64.ESTACK_HI+1,x + rts + .pend + +xor_w .proc + ; -- logical xor (word xor word -> byte) + lda c64.ESTACK_LO+2,x + ora c64.ESTACK_HI+2,x + beq + + lda #1 ++ sta c64.SCRATCH_ZPB1 + lda c64.ESTACK_LO+1,x + ora c64.ESTACK_HI+1,x + beq + + lda #1 ++ eor c64.SCRATCH_ZPB1 + inx + sta c64.ESTACK_LO+1,x + sta c64.ESTACK_HI+1,x + rts + .pend + abs_b .proc ; -- push abs(byte) on stack (as byte) diff --git a/compiler/src/prog8/ast/AST.kt b/compiler/src/prog8/ast/AST.kt index 7ff3901d9..c046cac34 100644 --- a/compiler/src/prog8/ast/AST.kt +++ b/compiler/src/prog8/ast/AST.kt @@ -2078,7 +2078,11 @@ private fun prog8Parser.IntegerliteralContext.toAst(): NumericLiteral { var datatype = DataType.UBYTE when (radix) { 10 -> { - integer = text.toInt() + integer = try { + text.toInt() + } catch(x: NumberFormatException) { + throw AstException("${toPosition()} invalid decimal literal ${x.message}") + } datatype = when(integer) { in 0..255 -> DataType.UBYTE in -128..127 -> DataType.BYTE @@ -2090,12 +2094,20 @@ private fun prog8Parser.IntegerliteralContext.toAst(): NumericLiteral { 2 -> { if(text.length>8) datatype = DataType.UWORD - integer = text.toInt(2) + try { + integer = text.toInt(2) + } catch(x: NumberFormatException) { + throw AstException("${toPosition()} invalid binary literal ${x.message}") + } } 16 -> { if(text.length>2) datatype = DataType.UWORD - integer = text.toInt(16) + try { + integer = text.toInt(16) + } catch(x: NumberFormatException) { + throw AstException("${toPosition()} invalid hexadecimal literal ${x.message}") + } } else -> throw FatalAstException("invalid radix") } diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 080e7d7c0..2a303a02e 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -16,9 +16,6 @@ import kotlin.math.abs class AssemblyError(msg: String) : RuntimeException(msg) -// TODO: code generation for POW instruction - - class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, val heap: HeapValues, val zeropage: Zeropage) { private val globalFloatConsts = mutableMapOf() private val assemblyLines = mutableListOf() @@ -887,30 +884,13 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, Opcode.IDIV_W -> " jsr prog8_lib.idiv_w" Opcode.IDIV_UW -> " jsr prog8_lib.idiv_uw" - Opcode.AND_BYTE -> { - """ - lda ${(ESTACK_LO + 2).toHex()},x - and ${(ESTACK_LO + 1).toHex()},x - inx - sta ${(ESTACK_LO + 1).toHex()},x - """ - } - Opcode.OR_BYTE -> { - """ - lda ${(ESTACK_LO + 2).toHex()},x - ora ${(ESTACK_LO + 1).toHex()},x - inx - sta ${(ESTACK_LO + 1).toHex()},x - """ - } - Opcode.XOR_BYTE -> { - """ - lda ${(ESTACK_LO + 2).toHex()},x - eor ${(ESTACK_LO + 1).toHex()},x - inx - sta ${(ESTACK_LO + 1).toHex()},x - """ - } + Opcode.AND_BYTE -> " jsr prog8_lib.and_b" + Opcode.OR_BYTE -> " jsr prog8_lib.or_b" + Opcode.XOR_BYTE -> " jsr prog8_lib.xor_b" + Opcode.AND_WORD -> " jsr prog8_lib.and_w" + Opcode.OR_WORD -> " jsr prog8_lib.or_w" + Opcode.XOR_WORD -> " jsr prog8_lib.xor_w" + Opcode.REMAINDER_UB -> " jsr prog8_lib.remainder_ub" Opcode.REMAINDER_UW -> " jsr prog8_lib.remainder_uw" diff --git a/examples/test.p8 b/examples/test.p8 index 332f3b396..70c11387a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,6 +5,8 @@ ; @todo test memset/memcopy (there's a bug in memcopy?) + ; @todo see looplabelproblem.p8 + ;ubyte x = rnd82() % 6 ; @todo fix compiler crash + always 0??? ;drawNext(rnd() & 7) ; @todo missing asm pattern @@ -15,7 +17,6 @@ ; if(X and c64scr.getcc(1,1)!=32) ... @todo the result value of the asmsub getcc is not put on the eval stack when used in an expression - ; (e1 and e2) @todo should not simply bitwise and e1 and e2 (same for or, xor) ; Y = (currentBlock[0] & sc) ; @todo missing assembly pattern for this bitand_byte @@ -23,21 +24,130 @@ sub start() { - Y=c64scr.getchr(30,20) - c64scr.print_ub(Y) + ubyte ub1 = %1001 + ubyte ub2 = %0111 + ubyte ub3 + byte b1 = %1001 + byte b2 = %0111 + byte b3 + uword uw1 = %0000100100000000 + uword uw2 = %0000001111000000 + uword uw3 + word w1 = %0000100100000000 + word w2 = %0000001111000000 + word w3 + +; ub3 = ub1 & ub2 +; b3 = b1 & b2 +; uw3 = uw1 & uw2 +; w3 = w1 & w2 +; c64scr.print("bitwise-and\n") +; c64scr.print_ubbin(1, ub3) +; c64.CHROUT('\n') +; c64scr.print_b(b3) +; c64.CHROUT('\n') +; c64scr.print_uwbin(1, uw3) +; c64.CHROUT('\n') +; c64scr.print_w(w3) +; c64.CHROUT('\n') +; +; ub3 = ub1 | ub2 +; b3 = b1 | b2 +; uw3 = uw1 | uw2 +; w3 = w1 | w2 +; c64scr.print("bitwise-or\n") +; c64scr.print_ubbin(1, ub3) +; c64.CHROUT('\n') +; c64scr.print_b(b3) +; c64.CHROUT('\n') +; c64scr.print_uwbin(1, uw3) +; c64.CHROUT('\n') +; c64scr.print_w(w3) +; c64.CHROUT('\n') +; +; ub3 = ub1 ^ ub2 +; b3 = b1 ^ b2 +; uw3 = uw1 ^ uw2 +; w3 = w1 ^ w2 +; c64scr.print("bitwise-xor\n") +; c64scr.print_ubbin(1,ub3) +; c64.CHROUT('\n') +; c64scr.print_b(b3) +; c64.CHROUT('\n') +; c64scr.print_uwbin(1,uw3) +; c64.CHROUT('\n') +; c64scr.print_w(w3) +; c64.CHROUT('\n') + + c64scr.print("logical-xor(w)\n") + uw1 = %1001110000001100 + uw2 = %0110001100110011 + uw3 = uw1 xor uw2 + c64scr.print_uwbin(1,uw3) + c64.CHROUT('\n') + c64scr.print_uwbin(1,%1001110000001100 xor %0110001100110011) + c64.CHROUT('\n') + c64.CHROUT('\n') + uw1 = %1111000011110000 + uw2 = %0011000000110000 + uw3 = uw1 xor uw2 + c64scr.print_uwbin(1,uw3) + c64.CHROUT('\n') + c64scr.print_uwbin(1,%1111000011110000 xor %0011000000110000) + c64.CHROUT('\n') + c64.CHROUT('\n') + uw1 = %1001110011111111 + uw2 = 0 + uw3 = uw1 xor uw2 + c64scr.print_uwbin(1,uw3) + c64.CHROUT('\n') + c64scr.print_uwbin(1,%1001110011111111 xor 0) + c64.CHROUT('\n') + c64.CHROUT('\n') + uw1 = 0 + uw2 = $2000 + uw3 = uw1 xor uw2 + c64scr.print_uwbin(1,uw3) + c64.CHROUT('\n') + c64scr.print_uwbin(1,0 xor $2000) + c64.CHROUT('\n') + c64.CHROUT('\n') + uw1 = $0020 + uw2 = $2000 + uw3 = uw1 xor uw2 + c64scr.print_uwbin(1,uw3) + c64.CHROUT('\n') + c64scr.print_uwbin(1,$0020 xor $2000) + c64.CHROUT('\n') + c64.CHROUT('\n') + uw1 = 0 + uw2 = 0 + uw3 = uw1 xor uw2 + c64scr.print_uwbin(1,uw3) + c64.CHROUT('\n') + c64scr.print_uwbin(1,0 xor 0) c64.CHROUT('\n') - Y=c64scr.getclr(30,20) - c64scr.print_ub(Y) c64.CHROUT('\n') - c64scr.setcc(30,20,123,4) - - Y=c64scr.getchr(30,20) - c64scr.print_ub(Y) - c64.CHROUT('\n') - Y=c64scr.getclr(30,20) - c64scr.print_ub(Y) - c64.CHROUT('\n') +; uw3 = uw1 and uw2 +; c64scr.print_uwbin(1,uw3) +; c64.CHROUT('\n') +; +; ub3 = ub1 or ub2 +; uw3 = uw1 or uw2 +; c64scr.print("logical-or\n") +; c64scr.print_ubbin(1,ub3) +; c64.CHROUT('\n') +; c64scr.print_uwbin(1,uw3) +; c64.CHROUT('\n') +; +; ub3 = ub1 xor ub2 +; uw3 = uw1 xor uw2 +; c64scr.print("logical-xor\n") +; c64scr.print_ubbin(1,ub3) +; c64.CHROUT('\n') +; c64scr.print_uwbin(1,uw3) +; c64.CHROUT('\n') } }