added missing bitwise and/or/xor asm code

This commit is contained in:
Irmen de Jong 2019-02-23 22:48:26 +01:00
parent c1d2b4601b
commit b0ad66bd04
4 changed files with 171 additions and 236 deletions

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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++
}
}