ByteByte

From Esolang
Jump to navigation Jump to search
This article is not detailed enough and needs to be expanded. Please help us by adding some more information.

The inital idea was by me (user:Javamannen) but I don't consider myself the "page owner". Anyone who feels he/she has something to contribute (spammers excluded) can edit this page directly. You don't have to go via the Talk page. --Javamannen 20:30, 14 October 2010 (UTC)

ByteByte is a class of byte move machines similar to ByteByteJump but with no jump address, only MOVE source and destination (hence "ByteByte"). Unlike Eugene Styer's byte MOVE machines however, there's not even a memory-mapped PC. Instead ByteByte has an n-bit cyclical program counter with wraparound behavior, where the goal is to make n as small as possible. Thus the machine runs in an endless loop consisting of 2n address words (or 2n bytes, depending on the machine implementation) at the start of memory.

Example: C implementation (untested) of a ByteByte machine with 32-bit addresses and an 8-bit program counter.

unsigned char mem[MEMSIZE]; // byte-addressable memory
unsigned int *mem32 = (unsigned int *)mem; //32-bit address words
unsigned char pc; // 8-bit program counter with wraparound
unsigned int a,b;
for (;;) {
  a = mem32[pc++];
  b = mem32[pc++];
  mem[b] = mem[a];
}

ByteByte can be extended to use any number of bits for the MOVE operation. The bigger machine family could be called "WordWord", and its simplest member "BitBit", whose operation simply is to copy a single bit from A to B (in a way the simplest possible OISC).

There are 3 basic machine parameters:

  • Data width. This is the number of bits copied; 8 bits for ByteByte. Can be any size in the general case of WordWord machines.
  • Address width; 32 bits in the above example, giving 4 GiB of addressable memory. Addresses must be 2 or more times bigger than data words for the machine to be able to compute with tables instead of an ALU.
  • Program counter width; 8 bits in the above example, chosen here mostly to make an easily understandable example (by using an unsigned char for the program counter we get the desired wraparound behavior for free).

The above example machine runs in an endless self-modifying loop with 128 MOVE instructions (256 address words) in the first 1024 bytes of memory. To simulate jumps you'd have to be able to fit the equivalent of a ByteByteJump interpreter into those 128 instruction slots. If that works, then the question becomes: how small can you make the loop (what's the smallest possible number of bits for the program counter)?

Hypothetical construction of such an interpreter
Given ByteByteJump doesn't involve any conditional branches whatsoever, it's likely that this would work - actually, I estimate 128 instruction slots to be overkill (at least for a 3-byte machine and assuming an optimized version of the design below).
Something like this, perhaps:
incIP: {
 ipL = page_inc[ipL]; // 2
 ipH = 0[page_carry_control[ipL], ipH]; // 4
};
srcH = 0[ipH, ipL]; // 3
incIP(); // 6
srcL = 0[ipH, ipL]; // 3
incIP(); // 6
dstH = 0[ipH, ipL]; // 3
incIP(); // 6
dstL = 0[ipH, ipL]; // 3
incIP(); // 6
0[%0^dstH, %0^dstL] = 0[%0^srcH, %0^srcL]; // 1
tmpIPH = 0[ipH, ipL]; // 3
incIP(); // 6
ipL = 0[ipH, ipL]; // 3
ipH = tmpIPH; // 1
The notation here uses [] to indicate indexing (which implies an additional instruction to copy from the index source unless it is an immediate), uses % to indicate a value is immediate, and uses ^ to indicate the attachment of a label to a specific index byte.
If anyone needs further details, write them down somewhere here.
This is unoptimized, mind - ideally each incIP instance would link to the next use with said operator, which would massively reduce the size.
This construction would use 50 instructions.
page_carry_control is a hypothetical page containing the upper address bytes of two other pages: the identity page (for values != 0) and the increment page, page_inc (for 0). Presumably, the various variables used here are defined elsewhere, though the aforementioned "chain" optimization would make them inline with the code itself. In either case, conceptually, this would basically be attached into a ByteByteJump program like a program header to make a ByteByte program, not really all that different to the usual adaptions for a different host machine.
--20kdc (talk) 18:09, 22 June 2020 (UTC)