diff --git a/compiler/res/prog8lib/prog8lib.asm b/compiler/res/prog8lib/prog8lib.asm index 6eb893f35..f34822dfc 100644 --- a/compiler/res/prog8lib/prog8lib.asm +++ b/compiler/res/prog8lib/prog8lib.asm @@ -106,6 +106,68 @@ not_word .proc rts .pend +bitand_b .proc + ; -- bitwise and (of 2 bytes) + lda c64.ESTACK_LO+2,x + and c64.ESTACK_LO+1,x + inx + sta c64.ESTACK_LO+1,x + rts + .pend + +bitor_b .proc + ; -- bitwise or (of 2 bytes) + lda c64.ESTACK_LO+2,x + ora c64.ESTACK_LO+1,x + inx + sta c64.ESTACK_LO+1,x + rts + .pend + +bitxor_b .proc + ; -- bitwise xor (of 2 bytes) + lda c64.ESTACK_LO+2,x + eor c64.ESTACK_LO+1,x + inx + sta c64.ESTACK_LO+1,x + rts + .pend + +bitand_w .proc + ; -- bitwise and (of 2 words) + lda c64.ESTACK_LO+2,x + and c64.ESTACK_LO+1,x + sta c64.ESTACK_LO+2,x + lda c64.ESTACK_HI+2,x + and c64.ESTACK_HI+1,x + sta c64.ESTACK_HI+2,x + inx + rts + .pend + +bitor_w .proc + ; -- bitwise or (of 2 words) + lda c64.ESTACK_LO+2,x + ora c64.ESTACK_LO+1,x + sta c64.ESTACK_LO+2,x + lda c64.ESTACK_HI+2,x + ora c64.ESTACK_HI+1,x + sta c64.ESTACK_HI+2,x + inx + rts + .pend + +bitxor_w .proc + ; -- bitwise xor (of 2 bytes) + lda c64.ESTACK_LO+2,x + eor c64.ESTACK_LO+1,x + sta c64.ESTACK_LO+2,x + lda c64.ESTACK_HI+2,x + eor c64.ESTACK_HI+1,x + sta c64.ESTACK_HI+2,x + inx + rts + .pend and_b .proc ; -- logical and (of 2 bytes) diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 2a303a02e..d4804c223 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -891,6 +891,13 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, Opcode.OR_WORD -> " jsr prog8_lib.or_w" Opcode.XOR_WORD -> " jsr prog8_lib.xor_w" + Opcode.BITAND_BYTE -> " jsr prog8_lib.bitand_b" + Opcode.BITOR_BYTE -> " jsr prog8_lib.bitor_b" + Opcode.BITXOR_BYTE -> " jsr prog8_lib.bitxor_b" + Opcode.BITAND_WORD -> " jsr prog8_lib.bitand_w" + Opcode.BITOR_WORD -> " jsr prog8_lib.bitor_w" + Opcode.BITXOR_WORD -> " jsr prog8_lib.bitxor_w" + Opcode.REMAINDER_UB -> " jsr prog8_lib.remainder_ub" Opcode.REMAINDER_UW -> " jsr prog8_lib.remainder_uw" diff --git a/examples/tehtriz.p8 b/examples/tehtriz.p8 index daadc0adf..599f464f6 100644 --- a/examples/tehtriz.p8 +++ b/examples/tehtriz.p8 @@ -7,17 +7,6 @@ const ubyte startXpos = boardOffsetX + 3 const ubyte startYpos = boardOffsetY - 2 - ubyte[4] blockI = [4, 5, 6, 7] ; note: special rotation - ubyte[4] blockJ = [0, 4, 5, 6] - ubyte[4] blockL = [2, 4, 5, 6] - ubyte[4] blockO = [1, 2, 5, 6] ; note: no rotation - ubyte[4] blockS = [1, 2, 4, 5] - ubyte[4] blockT = [1, 4, 5, 6] - ubyte[4] blockZ = [0, 1, 5, 6] - - ; block colors I, J, L, O, S, T, Z: cyan, blue, orange, yellow, green, purple, red - ubyte[7] blockColors = [3, 6, 8, 7, 5, 4, 2] - ubyte lines = 0 ubyte score = 0 ubyte xpos = startXpos @@ -65,7 +54,7 @@ waitkey: if key>='1' and key<='7' { ; select block type drawBlock(xpos, ypos, 32) - newCurrentBlock(key-'1') + blocklogic.newCurrentBlock(key-'1') drawBlock(xpos, ypos, 160) } else if key==157 or key==',' { @@ -115,7 +104,7 @@ waitkey: sub spawnNextBlock() { c64.TIME_LO = 0 - newCurrentBlock(nextBlock) + blocklogic.newCurrentBlock(nextBlock) nextBlock = rnd() % 7 drawNextBlock() xpos = startXpos @@ -170,7 +159,7 @@ waitkey: } for ubyte b in 7 to 0 step -1 { - newCurrentBlock(b) + blocklogic.newCurrentBlock(b) drawBlock(3, 3+b*3, 102) ; 102 = stipple } drawScore() @@ -192,46 +181,9 @@ waitkey: ; reuse the normal block draw routine (because we can't manipulate array pointers yet) ubyte prev = blocklogic.currentBlockNum - newCurrentBlock(nextBlock) + blocklogic.newCurrentBlock(nextBlock) drawBlock(28, 5, 160) - newCurrentBlock(prev) - } - - sub newCurrentBlock(ubyte block) { - memset(blocklogic.currentBlock, len(blocklogic.currentBlock), 0) - blocklogic.currentBlockNum = block - - ; @todo would be nice to have an explicit pointer type to reference the array, and code the loop only once... - ubyte blockCol = blockColors[block] - ubyte i - if block==0 { ; I - for i in blockI - blocklogic.currentBlock[i] = blockCol - } - else if block==1 { ; J - for i in blockJ - blocklogic.currentBlock[i] = blockCol - } - else if block==2 { ; L - for i in blockL - blocklogic.currentBlock[i] = blockCol - } - else if block==3 { ; O - for i in blockO - blocklogic.currentBlock[i] = blockCol - } - else if block==4 { ; S - for i in blockS - blocklogic.currentBlock[i] = blockCol - } - else if block==5 { ; T - for i in blockT - blocklogic.currentBlock[i] = blockCol - } - else if block==6 { ; Z - for i in blockZ - blocklogic.currentBlock[i] = blockCol - } + blocklogic.newCurrentBlock(prev) } sub drawBlock(ubyte x, ubyte y, ubyte character) { @@ -250,6 +202,54 @@ waitkey: ubyte[16] currentBlock ubyte[16] rotated + ; block colors I, J, L, O, S, T, Z: cyan, blue, orange, yellow, green, purple, red + ubyte[7] blockColors = [3, 6, 8, 7, 5, 4, 2] + ubyte[4] blockI = [4, 5, 6, 7] ; note: special rotation + ubyte[4] blockJ = [0, 4, 5, 6] + ubyte[4] blockL = [2, 4, 5, 6] + ubyte[4] blockO = [1, 2, 5, 6] ; note: no rotation + ubyte[4] blockS = [1, 2, 4, 5] + ubyte[4] blockT = [1, 4, 5, 6] + ubyte[4] blockZ = [0, 1, 5, 6] + + + sub newCurrentBlock(ubyte block) { + memset(currentBlock, len(currentBlock), 0) + currentBlockNum = block + + ; @todo would be nice to have an explicit pointer type to reference the array, and code the loop only once... + ubyte blockCol = blockColors[block] + ubyte i + if block==0 { ; I + for i in blockI + currentBlock[i] = blockCol + } + else if block==1 { ; J + for i in blockJ + currentBlock[i] = blockCol + } + else if block==2 { ; L + for i in blockL + currentBlock[i] = blockCol + } + else if block==3 { ; O + for i in blockO + currentBlock[i] = blockCol + } + else if block==4 { ; S + for i in blockS + currentBlock[i] = blockCol + } + else if block==5 { ; T + for i in blockT + currentBlock[i] = blockCol + } + else if block==6 { ; Z + for i in blockZ + currentBlock[i] = blockCol + } + } + sub rotateCW() { ; rotates the current block clockwise. if currentBlockNum==0 @@ -350,63 +350,48 @@ waitkey: return result sub canActuallyMoveLeft(ubyte xpos, ubyte ypos) -> ubyte { + ; @todo make this a generic subroutine that also works to check right and bottom collisions... + ubyte x = xpos-1 ubyte yp1 = ypos+1 ubyte yp2 = ypos+2 ubyte yp3 = ypos+3 - ubyte sc - ; @todo simplify expressions after bug fixes of boolean handling etc. - sc=c64scr.getchr(x, ypos) - if(currentBlock[0]!=0 and sc!=32) + ; @todo the boolean expression below currently doesn't work because the result of an asmsub call (getchr) is not put on the stack right now + if(currentBlock[0] and c64scr.getchr(x, ypos)!=32) return false - sc=c64scr.getchr(x, yp1) - if(currentBlock[4]!=0 and sc!=32) + if(currentBlock[4] and c64scr.getchr(x, yp1)!=32) return false - sc=c64scr.getchr(x, yp2) - if(currentBlock[8]!=0 and sc!=32) + if(currentBlock[8] and c64scr.getchr(x, yp2)!=32) return false - sc=c64scr.getchr(x, yp3) - if(currentBlock[12]!=0 and sc!=32) + if(currentBlock[12] and c64scr.getchr(x, yp3)!=32) return false x++ - sc=c64scr.getchr(x, ypos) - if(currentBlock[1]!=0 and sc!=32) + if(currentBlock[1] and c64scr.getchr(x, ypos)!=32) return false - sc=c64scr.getchr(x, yp1) - if(currentBlock[5]!=0 and sc!=32) + if(currentBlock[5] and c64scr.getchr(x, yp1)!=32) return false - sc=c64scr.getchr(x, yp2) - if(currentBlock[9]!=0 and sc!=32) + if(currentBlock[9] and c64scr.getchr(x, yp2)!=32) return false - sc=c64scr.getchr(x, yp3) - if(currentBlock[13]!=0 and sc!=32) + if(currentBlock[13] and c64scr.getchr(x, yp3)!=32) return false x++ - sc=c64scr.getchr(x, ypos) - if(currentBlock[2]!=0 and sc!=32) + if(currentBlock[2] and c64scr.getchr(x, ypos)!=32) return false - sc=c64scr.getchr(x, yp1) - if(currentBlock[6]!=0 and sc!=32) + if(currentBlock[6] and c64scr.getchr(x, yp1)!=32) return false - sc=c64scr.getchr(x, yp2) - if(currentBlock[10]!=0 and sc!=32) + if(currentBlock[10] and c64scr.getchr(x, yp2)!=32) return false - sc=c64scr.getchr(x, yp3) - if(currentBlock[14]!=0 and sc!=32) + if(currentBlock[14] and c64scr.getchr(x, yp3)!=32) return false x++ - sc=c64scr.getchr(x, ypos) - if(currentBlock[3]!=0 and sc!=32) + if(currentBlock[3] and c64scr.getchr(x, ypos)!=32) return false - sc=c64scr.getchr(x, yp1) - if(currentBlock[7]!=0 and sc!=32) + if(currentBlock[7] and c64scr.getchr(x, yp1)!=32) return false - sc=c64scr.getchr(x, yp2) - if(currentBlock[11]!=0 and sc!=32) + if(currentBlock[11] and c64scr.getchr(x, yp2)!=32) return false - sc=c64scr.getchr(x, yp3) - if(currentBlock[15]!=0 and sc!=32) + if(currentBlock[15] and c64scr.getchr(x, yp3)!=32) return false return true @@ -421,62 +406,49 @@ waitkey: return result sub canActuallyMoveRight(ubyte xpos, ubyte ypos) -> ubyte { + + ; @todo use the generic subroutine that also works to check right and bottom collisions... + ubyte x = xpos+4 ubyte yp1 = ypos+1 ubyte yp2 = ypos+2 ubyte yp3 = ypos+3 - ubyte sc - sc=c64scr.getchr(x, ypos) - if(currentBlock[3] and sc!=32) + ; @todo the boolean expression below currently doesn't work because the result of an asmsub call (getchr) is not put on the stack right now + if(currentBlock[3] and c64scr.getchr(x, ypos)!=32) return false - sc=c64scr.getchr(x, yp1) - if(currentBlock[7] and sc!=32) + if(currentBlock[7] and c64scr.getchr(x, yp1)!=32) return false - sc=c64scr.getchr(x, yp2) - if(currentBlock[11] and sc!=32) + if(currentBlock[11] and c64scr.getchr(x, yp2)!=32) return false - sc=c64scr.getchr(x, yp3) - if(currentBlock[15] and sc!=32) + if(currentBlock[15] and c64scr.getchr(x, yp3)!=32) return false x-- - sc=c64scr.getchr(x, ypos) - if(currentBlock[2] and sc!=32) + if(currentBlock[2] and c64scr.getchr(x, ypos)!=32) return false - sc=c64scr.getchr(x, yp1) - if(currentBlock[6] and sc!=32) + if(currentBlock[6] and c64scr.getchr(x, yp1)!=32) return false - sc=c64scr.getchr(x, yp2) - if(currentBlock[10] and sc!=32) + if(currentBlock[10] and c64scr.getchr(x, yp2)!=32) return false - sc=c64scr.getchr(x, yp3) - if(currentBlock[14] and sc!=32) + if(currentBlock[14] and c64scr.getchr(x, yp3)!=32) return false x-- - sc=c64scr.getchr(x, ypos) - if(currentBlock[1] and sc!=32) + if(currentBlock[1] and c64scr.getchr(x, ypos)!=32) return false - sc=c64scr.getchr(x, yp1) - if(currentBlock[5] and sc!=32) + if(currentBlock[5] and c64scr.getchr(x, yp1)!=32) return false - sc=c64scr.getchr(x, yp2) - if(currentBlock[9] and sc!=32) + if(currentBlock[9] and c64scr.getchr(x, yp2)!=32) return false - sc=c64scr.getchr(x, yp3) - if(currentBlock[13] and sc!=32) + if(currentBlock[13] and c64scr.getchr(x, yp3)!=32) return false x-- - sc=c64scr.getchr(x, ypos) - if(currentBlock[0] and sc!=32) + if(currentBlock[0] and c64scr.getchr(x, ypos)!=32) return false - sc=c64scr.getchr(x, yp1) - if(currentBlock[4] and sc!=32) + if(currentBlock[4] and c64scr.getchr(x, yp1)!=32) return false - sc=c64scr.getchr(x, yp2) - if(currentBlock[8] and sc!=32) + if(currentBlock[8] and c64scr.getchr(x, yp2)!=32) return false - sc=c64scr.getchr(x, yp3) - if(currentBlock[12] and sc!=32) + if(currentBlock[12] and c64scr.getchr(x, yp3)!=32) return false return true diff --git a/examples/test.p8 b/examples/test.p8 index 70c11387a..ee7f40c3b 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -9,21 +9,19 @@ ;ubyte x = rnd82() % 6 ; @todo fix compiler crash + always 0??? - ;drawNext(rnd() & 7) ; @todo missing asm pattern - ;ubyte[7] blockColors = [3, 6, 8, 7, 5, 4, 2] ;drawNext(n % len(blockColors)) ; @todo why is len a word here? ; 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 - ; Y = (currentBlock[0] & sc) ; @todo missing assembly pattern for this bitand_byte - - - ; mul_word_3 sub start() { + ubyte sc = 3 + ubyte[4] currentBlock + Y=currentBlock[0] & sc + ubyte ub1 = %1001 ubyte ub2 = %0111 ubyte ub3 @@ -37,117 +35,13 @@ 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') - 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') + sub drawNext(ubyte x) { + A=x + } + sub drawNextW(uword w) { + w++ } }