+@ (c) 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
+@ See LICENSE.txt file for copyright and license details.
+
#ifndef VVS_STDLIB_LOGIC
#define VVS_STDLIB_LOGIC
@ In twos-complement, NOT(X) = (-X)-1
SSTTN | PUSH -1
TSSN | MULTIPLY
-SSTTN | PUSH -1
+SSSTN | PUSH 1
TSST | SUBTRACT
NTN | RTS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@ and (101001)
+@ Description:
+@ Performs a bitwise AND on the TOS word.
+@ Call Stack:
+@ X
+@ Y
+@ Return Stack:
+@ X ^ Y
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSTSSTN | Mark: 101001 (and)
+
+@ Prepare the stack for computation.
+SSSSN | PUSH 0 (result)
+SSSTTTTTTN | PUSH 63 (shift counter)
+
+@ Loop through the bits one at a time.
+NSSVSSTSTSSTSSSSSSSSN | Mark: 00101001 00000000
+@ Prepare copy of X for the AND
+SNS | DUP
+SSSTSTN | PUSH 5
+NSTTTSSN | JSR > 1100 (deepdup)
+SNT | SWAP
+NSTTSTTSSN | JSR > 101100 (rshift)
+@ Prepare copy of Y for the AND
+SSSTSSN | PUSH 4
+NSTTTSSN | JSR > 1100 (deepdup)
+SSSTTN | PUSH 3
+NSTTTSSN | JSR > 1100 (deepdup)
+NSTTSTTSSN | JSR > 101100 (rshift)
+@ Do the AND and store in result.
+NSTTSSSSSSN | JSR > 1000000 (lowbitand)
+SSSTTN | PUSH 3
+NSTTSTTN | JSR > 1011 (stackrotatereverse)
+SSSTN | PUSH 1
+NSTTSTTSTN | JSR > 101101 (lshift)
+TSSS | ADD
+SSSTSN | PUSH 2
+NSTTSTSN | JSR > 1010 (stackrotate)
+@ Test for end of loop.
+SNS | DUP
+NTSSSTSTSSTSSSSSSSTN | BRZ > 00101001 00000001
+@ Decrement the counter and loop again.
+SSSTN | PUSH 1
+TSST | SUBTRACT
+NSNSSTSTSSTSSSSSSSSN | JMP > 00101001 00000000
+
+@ Clean up and return.
+NSSVSSTSTSSTSSSSSSSTN | Mark: 00101001 00000001
+SNN | DROP
+SNT | SWAP
+SNN | DROP
+SNT | SWAP
+SNN | DROP
+NTN | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@ or (101010)
+@ Description:
+@ Performs a bitwise OR on the TOS word.
+@ Call Stack:
+@ X
+@ Y
+@ Return Stack:
+@ X v Y
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSTSTSN | Mark: 101010 (or)
+NSTTSTSSSN | JSR > 101000 (not)
+SNT | SWAP
+NSTTSTSSSN | JSR > 101000 (not)
+NSTTSTSSTN | JSR > 101001 (and)
+NSTTSTSSSN | JSR > 101000 (not)
+NTN | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@ xor (101011)
+@ Description:
+@ Performs a bitwise XOR on the TOS word.
+@ Call Stack:
+@ X
+@ Y
+@ Return Stack:
+@ X xor Y
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSTSTTN | Mark: 101011 (xor)
+SNS | DUP
+SSSTTN | PUSH 3
+NSTTTSSN | JSR > 1100 (deepdup)
+NSTTSTSTSN | JSR > 101010 (or)
+SNT | SWAP
+SSSTTN | PUSH 3
+NSTTSTTN | JSR > 1011 (stackrotatereverse)
+NSTTSTSSTN | JSR > 101001 (and)
+NSTTSTSSSN | JSR > 101000 (not)
+NSTTSTSSTN | JSR > 101001 (and)
+NTN | RTS
+
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ rshift (101100)
@ X >> shiftcount
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTTSSN | Mark: 101100 (rshift)
-
-@ Test for loop completion first since it's allowable to shift by zero.
-NSSVSSTSTTSSSSSSSSSTN | Mark: 00101100 00000001
+@ Test for loop completion first since it is allowable to shift by zero.
SNS | DUP
NTSSSTSTTSSSSSSSSSSN | BRZ > 00101100 00000000
-@ Shift by one bit on each pass.
+
+@ Negative numbers need special handling.
SNT | SWAP
+SNS | DUP
+NTTSSTSTTSSSSSSSTSTN | BMI > 00101100 00000101
+
+@ Shift by one bit on each pass.
+NSSVSSTSTTSSSSSSSTSSN | Mark: 00101100 00000100
SSSTSN | PUSH 2
TSTS | DIVIDE
@ Decrement the counter.
SSSTN | PUSH 1
TSST | SUBTRACT
@ Loop again.
-NSNSSTSTTSSSSSSSSSTN | JMP > 00101100 00000001
+NSNTSTTSSN | JMP > 101100 (rshift)
-@ Clean up and return.
+@ Clean up
NSSVSSTSTTSSSSSSSSSSN | Mark: 00101100 00000000
SNN | DROP
NTN | RTS
+@ Found a negative number. Subtract one before proceeding if odd.
+NSSVSSTSTTSSSSSSSTSTN | Mark: 00101100 00000101
+SNS | DUP
+SSSTSN | PUSH 2
+TSTT | MODULO
+NTSSSTSTTSSSSSSSTSSN | BRZ > 00101100 00000100
+SSSTN | PUSH 1
+TSST | SUBTRACT
+NSNSSTSTTSSSSSSSTSSN | JMP > 00101100 00000100
+
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ lshift (101101)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTTSTN | Mark: 101101 (lshift)
-@ Test for loop completion first since it's allowable to shift by zero.
+@ Test for loop completion first since it is allowable to shift by zero.
NSSVSSTSTTSTSSSSSSSTN | Mark: 00101101 00000001
SNS | DUP
NTSSSTSTTSTSSSSSSSSN | BRZ > 00101101 00000000