Koyaanisqatsi: The WYSIWYG-style byte-code CPU
SVG-File (actual draft)
Ancient times are known to everyone not with immortal works from Homer's only, but also with the Pythagorean multiplication table, Euclidean geometry and the Archimedes screw and the Pi, which we learned to use only relatively recently. In antiquity the art was not only to be able to write poetry and prose, but to design catapults or battering tools also, now there are rigid frameworks, when the discovering the new another beautiful formula is a formal words play only.
Mathematics rules the modern world completely, cynically intertwining with the world of art, intruding with calculations in all spheres of our recreation and everyday life, when the colors of masterpieces turning into poisonous colours.
The same dry economy, with its numbers, forced Intel engineers to simplify the first processor, for the compatibility with not the best architecture of time, their sprint desire to throw their chip with ugly architecture to mass market. No one thought that the ugly machine code would become a world-class standard, which could not be looked at without pain and shame, where nobody thinking for switch from the latency nanoseconds to the aesthetic picture of their product: It is no longer important what such goals were then pursued by engineers, when superscalar the core of any modern processor, support for the x86 instructions has long been accomplished by the emulation level as a formality of marketing.
Koyaanisqatsi — like a cry from the heart!
In contrast to the well-known Intel processors, Koyaanisqatsi was conceived as a difficult named with easy to understand and learn to program it at the level of machine code in dump editors with no translators of a high-level languages.
The wild design of the processor was conceived as a joke controller with byte-code which ability to encode a script dump even without having to refer to the command table before learning them completely and whole task was set to design a simple processor device in which any of the 30 APRs can be replaced with any peripherals as sensors or motors in a unique opportunity to organize as direct interaction of all required devices without the need for mad high performance.
So, PICO-8 and Gigatron, as well as MegaProcessor or MyCPU, although developed by specialists, no one approached the issue with a esthetic of machine coding.
From start of design this processor, there was no goal of achieving at partial compatibility with any of the existing architecture by world leading industry.
But the main goal was to develop a processor, hexadecimal encoding in the dump of all instructions without assembler, when the byte nibbles themselves should represent the abbreviations of the instructions themselves — not binary encode some abstract bytecode with esoteric bit fields, like reg/mod bits in the x86.
Processor is based on a register file of four functional groups with ten cells each. Any ALU operations are possible on any registers, but exist simple rules for correct operation with them. Here we need to remember the purpose of these functional groups:
¹: D₉ can switching upto 256 pages of D₀…D₈ for any user-purpose units
|A₀…₉||Accumulators||A₀ is PSW of ALU|
|B₀…₉||Base / Block||B₀ store memory Block for RET-instruction|
|C₀…₉||Cell / Counter||C₀ store memory Cell for RET-instruction|
|D₀…₉||Device||Any in/out-Devices, like i8253, i8255 or i8257¹|
This processor is simple and doesn't have built-in any hardware for organizing stack operations, the B₀:C₀ registers saving the pointer for return to caller. If necessary, the programmer himself is obliged to take care of all operations with the stack and describe them with an algorithm, when should use library of virtual instructions for branching and call with a stack at the program level.
Koyaanisqatsi Command System
A bytecode are transparently encoded in WYSIWYG:“What I see means what I see”. Hexadecimal encoding is the abbreviation of the command itself, and everything was conceived so that most of the commands just perform understandable action.
- 00: HLT (program stop) — logical and harmonious code!
- 01…99: The BCD-code as prefixed Byte-Code-Data for expand next instruction
- A0…A9, B0…B9, C0…C9: Timeless prefixes for selecting the active register of the specified group — A₀…A₉, B₀…B₉, C₀…C₉ respectively
- D0…D9: Selection of the active device of the Devices group — D₀…D₉
- AA…AD: Timeless prefixes for choosing a combination of operands for ALU operations — A,A; A,B; A,C; A,D respectively
- BA…BD: Timeless prefixes for choosing a combination of operands for ALU operations — B,A; B,B; B,C; B,D respectively
- CA…CD: Timeless prefixes for choosing a combination of operands for ALU operations — C,A; C,B; C,C; C,D respectively
- DA…DD: Timeless prefixes for choosing a combination of operands for ALU operations — D,A; D,B; D,C; D,D respectively
- E0…EF: Calling an Extension via a subroutine — CALL 0xE000…0xEF00
- F0…FF: Call to the Function with the specified index — CALL 0xF000…0xFF00
- AE / BE / CE / DE: Conditional Return by active Flag existing (ZF / SF / CF / PO)
- AF / BF / CF / DF: Conditional Return by Fictive PSW-Flags (NZ / NS / NC / PE)
- 0A / 1A / 2A…9A: ALU-operation «Sum» (Add) over a group of operands — the index of the right operand is specified explicitly 0…9
- 0B / 1B / 2B…9B: ALU-operation «Subtraction» (suB) on a group of operands — the index of the right operand is specified explicitly 0…9
- 0C / 1C / 2C…9C: ALU-operation «Conjunction» (Conjunct / and) on a group of operands — the index of the right operand is specified explicitly 0…9
- 0D / 1D / 2D…9D: ALU-operation «Disjunct / or» on a group of operands — the index of the right operand is specified explicitly 0…9
- 0E / 1E / 2E…9E: ALU-operation «Exclusive OR» (Exclusive or / Eor / xor) on a group of operands — the index of the right operand is specified explicitly 0…9
- 0F / 1F / 2F…9F: MOV-operation «FOR» with group of operands — the index of the right operand is specified explicitly 0…9
Koyaaniskatsi programming basics
However, we shouldn't think that the WYSIWYG-processor requires nothing at all from an advanced user-programmer: You still have to overcome the minimum entry threshold…
For example, addition of values from registers A₁ and B₂ can be represented by the expression «A1 += B2» or the mnemonic notation «ADD A1,B2», what should be translate into machine code. The processor architecture is simple and based in Polish notation, we necessary to predefine the operands used in the operation.
Since the combination of registers «A1» and «B2» is used in the order «An,Bn», the machine code AB₁₆ must be specified under their definition. And indixes of specific operands is performed by codes A1₁₆ and B2₁₆ encoding a machine code. Since the index of the right operand is equal to «B2», then in the code of the ALU-operation «Add» it should be indicated in the left-hand nibble as 2A₁₆. It
becomes obvious that the code of the whole expression is «A1 AB B2 2A». The B₂ is no destination accumulator of result and it explicitly indicated in the ALU operation, the command byte «B2» can be excluded from the chain and this codes will be reduced to one combination of «A1 AB 2A» or «AB A1 2A».
The expression «A1 = A1 + B2 - B3 & B4 | B5 ^ B6» can be described by the code «A1 AB 2A 3B 4C 5D 6E», since each next instruction code contains the index of the right operand, which allows we to encode in a compact and eficient manner.
Raw files of project is placed here.
Raw Verilog-model placed at here.
Very angry emulator placed at here…
Original project index is hereru…