3 ms·
I like toys like this. I even have made a few of my own, doodled instruction set ideas on many scraps of paper, and so forth. It's a bit weird that this part
by Lerc 2y ago
I like toys like this. I even have made a few of my own, doodled instruction set ideas on many scraps of paper, and so forth.
It's a bit weird that this particular instruction set annoys me so much. Perhaps annoys is the wrong word, maybe irritates is better. The entire thing I can get behind except for the instruction encoding. The instructions are too large for the space available. 128k of ram for programs and 128k for screen (and workspace area, given sync), but at 8 bytes per instruction it eats up the limited resource too quickly.
I guess that irritation comes from the efficiency hacks that these constrained environments encourage. It revives an age of clever tricks to get the most of of a little. The instruction size pokes at that aesthetic like a lump in a pillow.
I'm not sure what would be a better solution while preserving simplicity. maybe a single extra dereference to turn
opcode arg1 arg2 arg3
@(IP) @(IP+1) @(IP+2) @(IP+3) ;; IP+=4
into
@(@IP) @(@IP+1) @(@IP+2) @(@IP+3) ;; IP+=1
which would be one system word per instruction lookup, from a dictionary of instructions in RAM (coders would have to be careful not to lose the ability to generate all constant values if they eliminated certain dictionary entries(
Tiny programs would get bigger , Larger programs would be smaller when they reuse instructions.
If you wanted to work against the idea of 'simplest' and embrace the notion of weird-features-because-of-technical-debt, you could make an 'upgraded' machine that has a second bank of 128k (64k words) as dedicated program memory, that is initialized at startup with the numbers 0x0000 to 0xffff. This would make the machine run SVC16 programs unmodified. You could then either have it use program ROMs or add a single instruction
StoreProgMem @progMem(@arg1+@arg3) =(@arg2+@arg3)
Which would enable writing the program space.
Egads, I've been nerd sniped!
- nine_k 2y agoWhy, there is a well-known approach to having constant-size, small opcodes: a data stack. The only non-constant size instruction would be the one that puts an immediate argument onto the stack. Jumps would pop the target address off the stack, too. The stack should be the width of the ALU, say, 32 bit, while the machine codes could be half a byte, like here. I'm very surprised this smallest machine is not a stack machine.
- ant6n 2y agoI feel similar about the instruction encoding. Another way could be to use registers, possibly just one register. Like in old machines that had an accumulator, which was implied. So „Add x“ adds x to the accumulator. In some sense, there is already a register file in the proposed VM, the whole memory. Another, related way, to reduce instruction size is to not allow all operands to be 16 bit, that is, have some registers that are more „special“ than others. For example, say the first 16 memory locations are special. Then it’s possible to have a Opcode, arg1, arg2, arg3 Encoding using 4 bits each, for 16 bit instructions. The problem is that some instructions will need a full 16 bit argument, for example some load immediate, or goto. Common ways to deal with that: 1) variable width instructions (16/32 bit) - makes machine less simple. 2) always use 32 bit instructions, meaning instructions are opcode, arg4bit, arg4bit, arg16bit. This is simpler, but still pretty wasteful for instruction length. Could also use opcode4bit, arg6bit, arg6bit, arg16bit This turns the first 64 memory locations into special registers, but uses awkward 6bit values. 3) use 8 bit immediates with hi/lo access (like arm). So then u have instructions like mov_hi dest4, imm8 nov_lo dest4, imm8 Setting the hi/lo byte of the register file (I.e. the first 16 memory locations). This in turn means there will be more instructions, they will not work directly on memory (like goto needs 2 loads). So while there is the nice property that instruction length equals word length, it also means more kinds of instructions (perhaps, like jump relative), more complicated instructions, and more instructions needing to be executed to accomplish similar tasks (eg 3 instructions for arbitrary jump). All these considerations are probably counter to wanting a maximally simple machine.
- zellyn 2y agoDo what Woz did and write a Sweet16 interpreter for the machine! https://en.wikipedia.org/wiki/SWEET16 https://en.wikipedia.org/wiki/SWEET16