The Fungus programming model is both very familiar and very alien. It can certainly be described in terms of concepts very familiar to the average low-level programmer.
Word Length
Fungus is an 18-bit word machine. The author strongly believes in machines with word lengths that are not a multiple of four. The multiple-of-three approach is a time-honoured one, with support from such giants as IBM and Digital. Besides, forcing programmers to start thinking in octal after well nigh thirty years of thinking in hexadecimal works in accordance with Fungus philosophy1.
The system deals with 18-bit words and pairs of 9-bit wos and rds. These are known in mainstream computer science as most signifncant and least significant half-words, respectively.
An 18-bit quantity can have one of three interpretations, as illustrated in the figure below.
- An 18-bit scalar value, in the range 0–262,143.
- A ℤ2 vector, where the wo and rd represents the
yandxordinates respectively. The wo and rd are in the range 0–511. - The two ordinates of the vector representation may be accessed individually using instruction masking. This allows Fungus to access individual wos and rds in memory.
To the programmer, it is most convenient to write Fungus numbers in base eight (octal), with three octal digits to a wo or rd and six octal digits to a word.
Byte order
Fungus does not have bytes, hence no byte order. However, this
specification does require that the wo (y
ordinate) is most significant. Hence, Fungus is wo-endian or
y-endian.
Address Space
For convenience, the address space is identical to the word length: 18
bits wide. The programmer is free to use vectors or scalars to address
memory, but Fungus convention uses vectors. Of the 18 address lines
provided by the microprocessor, the most significant 9
(A9–A17) correspond to the wo and the y ordinate. The least
significant 9 lines (A0–A8) correspond to the rd and the x
ordinate. Thus, the maximum amount of memory addressable by Fungus is
256 kwords2.
Unlike conventional architectures, this memory is organised as a two-dimensional array, with 512×512 elements. Hence the use of vectors to address memory.
Interestingly, this vector view of memory is neither alien nor
inconsistent with existing RAM technology. Most DRAM chips distinguish
between ‘row’ and ‘column’ addresses and use external signals like
CAS and RAS to change
the semantics of their address pins. It would appear that computer
technology has been building up to Fungus, doubtlessly the peak of CPU
design for the discerning sadomasochist.
The topology of the address space is toroidal. This is a side effect of the use of vector registers, as outlined in Section~\ref{sec:regs}. An intentional lack of overflow detection in the ALU allows wrapping around of vector ordinates to simulate this popular yet simple Funge topology.
To further explain the topology, the programmer may address memory
using vectors or scalars (though vectors are preferred). When
addressing memory as a one-dimensional array by using scalar
arithmetic, address 001777 + 1 yields
address 002000. This is congruent with memory on
conventional architectures. In vector mode, address 001777 +
1 is equivalent to (001, 777) + (000, 001): this
wraps around the X axis to (001, 000)
or 001000. This is congruent with the toroidal topology
and the way Funges generally work.
Memory
Memory also consists of 18-bit words. Fungus only reads and writes 18-bit quantities. Thus, the 256 kwords of accessible memory is 18-bits wide.
For the byte-o-philiac reader, a Fungus word is 2.25 bytes. A single 512-word row or column of memory is 1,152 bytes (1.125 kbytes). The entire address space corresponds to 589,824 bytes, or 576 kbytes. This, however, is irrelevant: values cannot be accessed in byte-sized chunks but only in word-sized quanta.
The address space may be expanded using memory mapping, swapping and paging techniques with external, kludgy hardware. Again, this is consistent with Fungus design.
Registers
As seen in the figure below, Fungus has eight word-wide
registers. Registers may be treated as 18-bit scalar values and
two-dimensional vectors with 9-bit wo and rd ordinates. The registers
are referred to by number as $0–$7 (pronounced like
‘big-money-zero’), or by name. All registers can be used as general
purpose registers by the programmer who points loaded guns at her
feet, but in reality, all but three registers have special uses:
$0or0:-
A source of zeroes. In compliance with Fungus design philosophy,
this register is writable. Changing it, however, will
massively disrupt CPU operation as
$0is used internally by CPU picocode. There is purposefully no guard against this. Low level programming should be a disciplined discipline. $1orPC:- The program counter. Like all other CPUs, this
register points to the next instruction to be fetched from
memory. Unlike all other CPUs, the
PCis a vector. $2orΔPC:- The program counter delta (velocity). This vector value is added to the
PCvector immediately after an instruction fetch. The ordinate values are arbitrary, though values of -1 (left or up), 0 (no change) and 1 (right, down) are typical. Here are a few examples of usefulΔPCvalues:-
(000,000): halts the CPU (PC stops moving). -
(777,000): PC moves to the north. -
(001,000): PC moves to the south. -
(000,777): PC moves to the east. -
(000,001): PC moves to the west.
Diagonal movement is, of course possible, as are flying PCs, though these should not be attempted by the faint of heart.
-
$3orA:- the first general purpose register.
$4orB:- the second general purpose register.
$5orC:- the third and last general purpose register.
$6orD:$7orE:- Likewise, this register may hold temporary copies of
the
PCregister during aTRP.
A general purpose register. This one is used to
store temporary copies of the ΔPC register by the TRP
command. It can still be used outside system traps/micro-instructions.








Add new comment