# LRONETWO

LRONETWO is single instruction machine created by SophiaCristina that uses a pretty simple logic to work. I think that it is very unlikely that this machine is remotely useful considering that there is no way to receive an input of its own without modifying it completely to the point of making the code unreadable for the correct operations. It would be interesting if someone could do something useful with this.

## Logic

The logic is super simple, you read the program in a ROM and the ROM modifies a memory.

If the ROM bit is '1' it moves the memory pointer to the left, if it is '0', to the right;

If the value in the pointed memory location is '0', it flips and changes one position, and if the value is '1', it flips and changes two positions.

Memory works like a circular buffer, so if the pointer crosses the end or beginning of memory addresses, it will go back to the beginning or end of memory.

Example:

ROM bits:

[0,1,0,1]

Memory:

[0,0,1]

ROM[0] is '0', so it is set to move to the right.

Memory[0] is '0', so it flips and moves one space to the right:

The memory is now:

[1,*0,1]

ROM[1] is '1', so it is set to move left.

Memory[1] is '0', so it flips and moves one space to the left:

The memory is now:

[*1,1,1]

ROM[2] is '0', so it's set to move to the right.

Memory[0] is '1', so it flips and moves two spaces to the right:

The memory is now:

[0,1,*1]

ROM[3] is '1', so it moves to the left.

Memory[2] is '1', so it flips and moves two spaces to the right:

The memory is now:

[*0,1,0]

## Machine implementation

This is a machine implementation in C++:

```template <const uint64_t MemSize, const uint64_t ROMSize>
class LRONETWOMachine
{
private:
uint8_t* MEM = nullptr;
uint8_t* ROM = nullptr;
uint64_t MEMByte = 0, ROMByte = 0;
int8_t MEMBit = 0; uint8_t ROMBit = 0;

public:
LRONETWOMachine(uint8_t* InsertMem, uint8_t* InsertROM) { MEM = InsertMem; ROM = InsertROM; }
~LRONETWOMachine() {}

int Run()
{
for (uint64_t n = 0; n < ROMSize * 8; ++n)
{
if (!MEM || !ROM) { return(-1); }
if (ROM[ROMByte] & 1 << (7 - ROMBit))
{
if (MEM[MEMByte] & 1 << (7 - MEMBit))
{ MEM[MEMByte] ^= 1 << (7 - MEMBit); MEMBit -= 2; }
else { MEM[MEMByte] ^= 1 << (7 - MEMBit); --MEMBit; }
++ROMBit;
}
else
{
if (MEM[MEMByte] & 1 << (7 - MEMBit))
{ MEM[MEMByte] ^= 1 << (7 - MEMBit); MEMBit += 2; }
else { MEM[MEMByte] ^= 1 << (7 - MEMBit); ++MEMBit; }
++ROMBit;
}
if (MEMBit > 7) { ++MEMByte; MEMByte %= MemSize; MEMBit %= 8; }
else if (MEMBit < 0)
{ --MEMByte; if (MEMByte >= MemSize) { MEMByte = MemSize - 1; } MEMBit += 8; }
if (ROMBit > 7) { ++ROMByte; ROMByte %= ROMSize; ROMBit %= 8; }
}
ROMByte = 0; ROMBit = 0; MEMByte = 0; MEMBit = 0;
return(0);
}
};
```

## Intuitive explanation

How to issue a "Hello" from the machine:

```MEM      ROM
10000000 0
*
11000000 1
*
01000000 0
*
01100000 0
*
01110000 1
*
01010000 0
*
01011000 1
*
01001000 0
*
01001100 0
*
01001110 1
*
01001010 0
*
01001011 1
*
01001001 0
00000000
*
10000000 l
01001001
*
01001000 0 = H
10000000
*
11000000 1
*
01000000 0
*
01100000 0
*
01110000 0
*
01111000 1
*
01101000 0
*
01101100 1
*
01100100 0
*
01100110 0
*
01100111 l
*
01100101 0 = e
00000000
*
10000000 0
*
11000000 1
*
01000000 0
*
01100000 0
*
01110000 0
*
01111000 1
*
01101000 0
*
01101100 0
*
01101110 0
*
01101111 1
*
01101101 0
00000000
*
10000000 1
01101101
*
01101100 0 = l
10000000
*
11000000 1
*
01000000 0
*
01100000 0
*
01110000 0
*
01111000 1
*
01101000 0
*
01101100 0
*
01101110 0
*
01101111 1
*
01101101 0
00000000
*
10000000 1
01101101
*
01101100 0 = l
10000000
*
11000000 1
*
01000000 0
*
01100000 0
*
01110000 0
*
01111000 1
*
01101000 0
*
01101100 0
*
01101110 0
*
01101111 0 = o
00000000
*

ROM:
010010100101010 H
10001010010     e
0100010001010   l
100010001010    l
10001000        o
01001010 01010101 00010100 10010001 00010101 00010001 01010001 000
74       85       20       145      21       17       81       0
```