As address 0xC0000000 and 0xD0000000 an example.
# # +---- qMem1 = [0xC0000000] # +---- qMem1 = Mem8[0xC0000000][:] # +---- Mem8[0xC0000000] # | bit bit # | 0 1 # | +---+---------+ # | Address V V | # \ +-----------+---+---+---+---+---+---+---+---+ | # +-------> |0xC0000000 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | # +-----------+---+---+---+---+---+---+---+---+ | # ^ ^ ^ | # | | | | # pReg1 = Mem8[0xC0000000][1:2] --+ | | | # pReg1[0] -----------------------+ | | | # rReg1 = pReg1 ------------------+---+ | | # Mem8[0xC0000000][1:2] ----------+---+ | | # Mem8[0xC0000000][2:1] ----------+---+ | | # | | # Mem8[0xC0000000][-1] -----------------------------------+ | # | # +---- qMem2 = Mem8[0xD0000000][:] | # +---- Mem8[0xD0000000] | # +---- Mem8[0xD0000000][:] | # | | # | +-------------------------------------------------------+ # | | # | +--- cReg1 = Mem8[Mem8[0xC0000000][5:6], Mem8[0xD0000000][3:5]] # | +--- cReg1 = Mem8[pReg1, pReg2] # | +--- cReg2 = cReg1 # | | bit bit # | | 2 3 # | +--------------------------+---+ # | | | # | Address V V # \ +-----------+---+---+---+---+---+---+---+---+ # +-> |0xD0000000 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | # +-----------+---+---+---+---+---+---+---+---+ # ^ ^ ^ # pReg2 = Mem8[0xD0000000][5:6] | | | # Mem8[0xD0000000][5:6] -------------------+---+ | # Mem8[0xD0000000][6:5] -------------------+---+ | # | # Mem8[0xD0000000][-1] ----------------------------+ # from LoLeOp.Mem import Mem8, Mem16, Mem32, Mem64 qMem1 = Mem8[0xC0000000] pReg1 = Mem8[0xC0000000][1:2] qMem2 = Mem8[0xD0000000] pReg2 = Mem8[0xD0000000][5:6] cReg1 = Mem8[Mem8[0xC0000000][5:6], Mem8[0xD0000000][3:5]] cReg2 = Mem8[pReg1, pReg2]
Mem8[0xC0000000] means an object pointer to address 0xC0000000.
qMem1 = Mem8[0xC0000000] means qMem1 is an variable pointer to address 0xC0000000.
If value at address 0xC0000000 is changed by hardware or by another process,
value of qMem1 and Mem8[0xC0000000] pointer to are changed at next statement for reading
qMem1 and Mem8[0xC0000000].
qMem2 and Mem8[0xD0000000] have the same behavior as qMem1.
pReg1 and Mem8[0xC0000000][1:2] means bit 1 and bit 2 value of address 0xC0000000.
pReg2 and Mem8[0xC0000000][5:6] have the same behavior as pReg1.
cReg1 and cReg2 are cascade bits status from Mem8[0xC0000000][5:6] and Mem8[0xD0000000][3:5].
Python program with LoLeOp library:
from LoLeOp.Mem import Mem8, Mem16, Mem32, Mem64 # # // C language # printf ("0x%02X\n", *(volatile unsigned char *)0xC0000000); # print "0x%02X" % Mem8[0xC0000000] # # Create variable qMem1 pointer to 0xC0000000 # # // C language, similar behavior not all the same as LoLeOp # volatile unsigned char *qMem1 = (volatile unsigned char *)0xC0000000; # qMem1 = Mem8[0xC0000000] But Python statement using LoLeOp library qMem1[0] # This means the 0 bit of address 0xC0000000 with LoLeOp data type. is not equal to C language statment qMem1[0]; // This means: (volatile unsigned char *)0xC0000000[0]; # # Create variable rMem1 with the same address of qMem1 # # // C language # volatile unsigned char *rMem1 = qMem1 # rMem1 = qMem1
Get bits value from memory address 0xC0000000.
Mem8[0xC0000000][1]
Get last bit(bit 7) value in address 0xC0000000
Mem8[0xC0000000][-1]
Get bit 2 and set bit 1 value in address 0xC0000000
Mem8[0xC0000000][2:1] Mem8[0xC0000000][1:2] # It is another statement.
Set pReg1 as object for bit 2 and bit 1 in address 0xC0000000
qMem1 = Mem8[0xC0000000] pReg1 = Mem8[0xC0000000][2:1] pReg1 = Mem8[0xC0000000][1:2] # It is another statement. pReg1 = qMem1[1:2] pReg1 = qMem1[2:1]
Following C language has similar result with above python code. But it is
hard to get the same result as LoLeOp.
unsigned char pReg1 (void) { volatile unsigned char *qMem1 = (volatile unsigned char *)0xC0000000; return (*qMem1 >> 1) & 0x03; }
Get bit 0 of pReg1, that is Mem8[0xC0000000][1], too.
pReg1[0]
Set rReg1 as pReg1, that is rReg1 is Mem8[0xC0000000][2:1], too.
rReg1 = pReg1
Get bit 0 of rReg1, that is Mem8[0xC0000000][1], too.
rReg1[0]
Get all bit in rReg1, that is Mem8[0xC0000000][2:1], too.
rReg1[:] rReg1[0:-1] rReg1[-1:0]
Set sReg1 as bit 0 of rReg1, that is sReg1 is Mem8[0xC0000000][1], too.
sReg1 = rReg1[0]
Set value of address 0xC0000000 as 3. Python code with LoLeOp library:
from LoLeOp.Mem import Mem8, Mem16, Mem32, Mem64 qMem1 = Mem8[0xC0000000] rMem1 = qMem1 # # *(volatile unsigned char *)0xC0000000 = (unsigned char)3; # following Python statement are the same. # Mem8[0xC0000000] = 3 qMem1[:] = 3 rMem1[:] = 3
Note: qMem1 = 3, qMem1's data type will be int, not LoLeOp Mem8.
Set bits value in memory address 0xC0000000.
Mem8[0xC0000000][1]
Set last bit(bit 7) value in address 0xC0000000 as 1
Mem8[0xC0000000][-1] = 1
Set bit 2 and set bit 1 in address 0xC0000000 as 2
Mem8[0xC0000000][2:1] = 2 Mem8[0xC0000000][1:2] = 2 # It is another statement.
Set pReg1 as bit 2 and set bit 1 in address 0xC0000000
pReg1 = Mem8[0xC0000000][2:1]
And set bit 1 of pReg1 as 0.
pReg1 = Mem8[0xC0000000][2:1] pReg1[1] = 0 Mem8[0xC0000000][2] = 0
LoLeOp are new created class (data type) from current Python programming.
It transfer to integer as following python code
qMem1 = Mem8[0xC0000000] pReg1 = Mem8[0xC0000000][1:2] int (Mem8[0xC0000000]) int (qMem1) int (pReg1) print "%02X" % qMem1[0xC0000000] print "%02X" % qMem1 print "%02X" % pReg1
It output to string as following python code
qMem1 = Mem8[0xC0000000] pReg1 = Mem8[0xC0000000][1:2] str (Mem8[0xC0000000]) str (qMem1) str (pReg1) print "%02X", Mem8[0xC0000000] print "%02X", qMem1 print "%02X", pReg1
Return bit numbers of LoLeOp object
len (Mem8[0xC0000000]) # return 8 len (pReg1) # return 2 len (qMem1) # return 8
LoLeOp support these logic operation and return boolean data type (True or False).
These are legal logic operation
qMem1 = Mem8[0xC0000000] qMem2 = Mem8[0xD0000000] pReg1 = Mem8[0xC0000000][1:2] pReg2 = Mem8[0xD0000000][6:5] Mem8[0xC0000000] < Mem8[0xD0000000] Mem8[0xC0000000][2:5] < Mem8[0xD0000000][2:5] qMem1 < qMem2 qMem1[2:5] < qMem2[2:5] pReg1 < pReg2 pReg1[1] < pReg2[1] Mem8[0xC0000000] <= Mem8[0xD0000000] Mem8[0xC0000000][2:5] <= Mem8[0xD0000000][2:5] qMem1 <= qMem2 qMem1[2:5] <= qMem2[2:5] pReg1 <= pReg2 pReg1[1] <= pReg2[1] Mem8[0xC0000000] == Mem8[0xD0000000] Mem8[0xC0000000][2:5] == Mem8[0xD0000000][2:5] qMem1 == qMem2 qMem1[2:5] == qMem2[2:5] pReg1 == pReg2 pReg1[1] == pReg2[1] Mem8[0xC0000000] != Mem8[0xD0000000] Mem8[0xC0000000][2:5] != Mem8[0xD0000000][2:5] qMem1 != qMem2 qMem1[2:5] != qMem2[2:5] pReg1 != pReg2 pReg1[1] != pReg2[1] Mem8[0xC0000000] > Mem8[0xD0000000] Mem8[0xC0000000][2:5] > Mem8[0xD0000000][2:5] qMem1 > qMem2 qMem1[2:5] > qMem2[2:5] pReg1 > pReg2 pReg1[1] > pReg2[1] Mem8[0xC0000000] >= Mem8[0xD0000000] Mem8[0xC0000000][2:5] >= Mem8[0xD0000000][2:5] qMem1 >= qMem2 qMem1[2:5] >= qMem2[2:5] pReg1 >= pReg2 pReg1[1] >= pReg2[1] not pReg1
All LoLeOp arithmetic operation and bit operation return integer data type. that is
qMem1 = Mem8[0xC0000000] qMem2 = Mem8[0xD0000000] pReg1 = Mem8[0xC0000000][1:2] pReg2 = Mem8[0xD0000000][6:5] TestValue1 = Mem8[0xC0000000] + Mem8[0xD0000000] TestValue2 = qMem1 - qMem2 TestValue3 = pReg1 * pReg2 TestValue4 = qMem1 / qMem2 TestValue5 = qMem1 TestValue5 += qMem1 TestValue6 = qMem1 << 3 TestValue7 = qMem1 >> 1 TestValue8 = qMem1 & qMem2 TestValue9 = qMem1 | qMem2 TestValue10 = qMem1 ^ qMem2
TestValue[1...10] are ineteger data type, not LoLeOp type.
LoLeOp support any arithmetic operation and bit operation defined in Python.
Another note:
Mem8[0xC0000000] += 3 is equal to these statement t = Mem8[0xC0000000] + 3 # t data type is integer Mem8[0xC0000000] = 3 # write value t back to Mem8[0xD0000000]
cascade in LoLeOp is another data type present bits in different address
qMem1 = Mem8[0xC0000000] qMem2 = Mem8[0xD0000000] cReg1 = Mem8[Mem8[0xC0000000][5:6], Mem8[0xD0000000][3:5]] cReg1 = Mem8[pReg1, pReg2] cReg2 = cReg1
cReg1 and cReg2 are the same with following bit sequence present when it
convert to integer. Its length is 4 (4 bits width)
bit4 bit3 bit2 bit1 bit0 qMem2[5] qMem2[4] qMem2[3] qMem1[6] qMem1[5]
Any read/write operation affect corresponding bit position.