NOTE: Planning upgrades around 8pm-10pm UTC today. Expect some downtime and possibly read-only wiki. Avoid major editing sessions during that time.

4 trivingits, 529 trivingytes

From Esolang
Jump to navigation Jump to search

4 trivingits, 529 trivingytes, another prime-number ASM designed by PSTF.

Also known as TAL assembly language where T stands for trivigintal, Base-23.

This is designed for a 4-trivingit CPU which is named Q23 CPU. Q stands for "quattor", which is 4 in Latin.

If a number isn't written in decimal, it'll be put in parentheses in the document with a subscript showing its base.

Terminology

  • Trivingit: a digit23.
  • Trivingyte: two trivingits.
  • CPU Word Size: 4 trivingits (2 trivingytes)
  • Integer Range: 0 to 23⁴ − 1 = 279,840
  • Memory Size: 529 trivingytes = 1058 trivingits
  • Address Space: 0 to 528 (fits perfectly in 2 trivingits, since (100)23 = 529)
  • Registers: 8 general-purpose registers (R0–R7), each 4 trivingits wide. R0 is hardwired to zero.
  • Flags: Zero (Z), Negative (N), Carry (C) – set by ADD, SUB, CMP and other arithmetic things.
  • Program Counter: 4 trivingits (addresses up to 279,840, though only 0–528 are used)
  • I/O: Memory-mapped at address 528 (the last byte). Reading yields input; writing outputs a character.

Codepage

 0123456789abcdefghijklm
0␀␁␂␃␄␅␆␇␈␉␊␋␌␍␎␏␐␑␒␓␔␕␖
1␗␘␙␚␛␜␝␞␟ !"#$%&'()*+,-
2./0123456789:;<=>?@ABCDE
3FGHIJKLMNOPQRSTUVWXYZ[\]
4^_`abcdefghijklmnopqrstu
5vwxyz{|}~␡⎕⍈⌸⌹⌺⌻⌼⍁⍂⍃⍄⍇⍌⍍
6⍐⍓⍔⍗⍞⍠⍯⍰⌷⌽⌾⌿⍀⍅⍆⍊⍉⍋ ¡¢£¥¦
7§¨©ª«¬№®¯°±²³´µ¶·¸¹º»¼
8½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔ
9ÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëì
aíîïðñòóôõö÷øùúûüýþÿ─│┌┐
b└┘├┤┬┴┼━┃┏┓┗┛┣┫┳┻╋╱╲╳═║
c╔╗╚╝╠╣╦╩╬╭╮╯╰╴╵╶╷⍬←↑→↓↖
d↗↘↙↔↕█▀▄▌▐ĀāĂ㥹ĆćĈĉĊċČ
ečĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģ
fĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺ
gĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐő
hŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨ
iũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ
j⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞√∑∈∏∫∴∵≤≥≠≈
k░▒▓ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ™ΣΤΥ
lΦΧΨΩαβγδεζηθικλμνξοπρςσ
mτυφχψωΆΈΉΊΌΎΏάέήίόύώ⅐⅑⅒

Instruction Set Architecture (ISA)

All instructions are exactly 4 trivingits long.

There are three encoding formats:

  • Format R (Register–Register)
    [Op] [Rd] [Rs1] [Rs2]
  • Format I (Immediate / Address for LDI)
    [Op] [Rd] [Imm_hi] [Imm_lo] — Immediate range = 0 to 528 (23² values)
  • Format J (Jump / Branch)
    [Op] [Addr_hi] [Addr_mid] [Addr_lo] — Address range = 0 to 528

Instruction Table

Mnemonic			Opcode	Format	Semantics											Flags
ADD Rd, Rs1, Rs2	0		R		Rd = Rs1 + Rs2 (mod 23⁴)							Z, N, C
SUB Rd, Rs1, Rs2	1		R		Rd = Rs1 - Rs2 (mod 23⁴)							Z, N, C
CMP Rs1, Rs2		2		R		Compute Rs1 - Rs2; discard result, set flags only	Z, N, C
LOAD Rd, [Rs]		3		R		Load 1 word (4 trivingits) from memory address Rs 	–
									into Rd. Address must be even.
STORE Rs, [Rd]		4		R		Store 1 word (4 trivingits) from Rs to memory		–
									address Rd. Address must be even.	
LDI Rd, Imm			5		I		Load a 2-trivigit immediate (0–528) into the 		–
									lower half of Rd; upper half zeroed.
JMP Addr			6		J		Unconditional jump to Addr (0–528)					–
JZ Addr				7		J		Jump to Addr if Zero flag = 1						–
JNZ Addr			8		J		Jump to Addr if Zero flag = 0						–
HALT				9		–		Stop execution (opcode 9, rest zeroed)				–
LDH Rd, Imm			A		I		Load a 2-trivigit immediate (0–528) into the 		–
									higher half of Rd; upper half zeroed.
MUL Rd, Rs1, Rs2	B		R		Rd = Rs1 × Rs2 (mod 23⁴)							Z, N, C
DIV Rd, Rs1, Rs2	C		R		Rd = Rs1 ÷ Rs2 (mod 23⁴) rounded down				Z, N, C
MOD Rd, Rs1, Rs2	D		R		Rd = Rs1 mod Rs2 (mod 23⁴)							Z, N, C
NOP					M		–		No operation										Z, N, C

Note: LOAD/STORE operate on full words (2 trivingytes = 4 trivingits). The address must be even. For byte (trivingyte) access, one can use the pseudo-instructions described later.

Turing Completeness Proof

A CPU of this is Turing-complete if it can simulate a SUBLEQ (Subtract and Branch if Less-than-or-Equal to Zero) instruction, which is known to be universal.

We can simulate SUBLEQ A, B, C (memory locations) using our ISA:

  1. LOAD R1, [A] – Load value at A into R1
  2. LOAD R2, [B] – Load value at B into R2
  3. SUB R3, R1, R2 – R3 = R1 - R2
  4. STORE R3, [A] – Store result back to A
  5. CMP R3, R0 – Compare result with zero (R0 is hardwired zero)
  6. JZ C – If result ≤ 0 (zero flag set), jump to address C

Because we have:

  1. Arithmetic (SUB)
  2. Indirect memory access (LOAD/STORE)
  3. Conditional branching (JZ)

we can implement any SUBLEQ program. Given unbounded memory extension (abstractly), the Q23 ISA is Turing-complete. In practice, with 529 bytes, it is a powerful finite-state machine, but the instruction set itself is universal.

Assembly Language Syntax & Directives

  • Comments: ; to end of line
  • Labels: label_name:
  • Registers: R0 through R7
  • Numbers: Trivigintal by default, or use 0b/0d/0x for binary/decimal/hex (converted to base-23 internally)
Directive		Description
.org N			Set the current assembly address to N (0–528)
.word V			Store a 4-trivigit value (V must be ≤ 279,840)
.byte V			Store a 2-trivigit value (V must be ≤ 528)
.asciiz "str"	Store a null-terminated string as trivingytes (Codepage → numeric)

Pseudo-instructions (expanded by the assembler):

  • MOV Rd, Rs → ADD Rd, Rs, R0
  • LOADB Rd, [Rs] → loads a single trivingyte (uses bit masking with AND – requires a mask constant)
  • STOREB Rs, [Rd] → stores a single trivingyte (using OR and AND)

Example Programs

Hello, World!

.org 100               ; Program starts at address 100

start:
    LDI R1, str        ; R1 = address of string (0)
    LDI R2, 0          ; R2 = index counter
    LDI R3, io_port    ; R3 = 528 (I/O port)

loop:
    ADD R4, R1, R2     ; R4 = str + index
    LOADB R5, [R4]     ; R5 = next character (byte load pseudo-instruction)
    CMP R5, R0         ; Compare with R0 (zero)
    JZ done            ; If null terminator, finish
    STOREB R5, [R3]    ; Output character to port 528
    LDI R6, 1
    ADD R2, R2, R6     ; index++
    JMP loop

done:
    HALT

.org 0                 ; String stored at beginning of memory
str:
    .asciiz "Hello, World!\n"

io_port:
    .byte 528          ; I/O address constant

Fibonacci

.org 200

main:
    LDI R1, 0          ; R1 = Fib(0)
    LDI R2, 1          ; R2 = Fib(1)
    LDI R3, 10         ; R3 = counter (n)
    LDI R4, 1          ; R4 = constant 1
    LDI R5, result     ; R5 = address to store result (500)

loop:
    CMP R3, R0         ; Compare counter with 0
    JZ done
    ADD R6, R1, R2     ; R6 = R1 + R2
    MOV R1, R2         ; R1 = R2
    MOV R2, R6         ; R2 = R6
    SUB R3, R3, R4     ; counter--
    JMP loop

done:
    STORE R2, [R5]     ; Store final Fibonacci number
    HALT

.org 500
result:
    .word 0            ; Reserve space for result

Machine Code Encoding Example

Let’s encode ADD R1, R2, R3:

  • Opcode for ADD = 0
  • Rd = 1, Rs1 = 2, Rs2 = 3
  • Machine code (base-23 digits): [0] [1] [2] [3] → displayed as "0123"

For JMP 0d100, its machine code is [6] [048] → "6048" since 100 equals (48)23.

Summary

The Q23 CPU with its TAL assembly language provides a clean, mathematically consistent base-23 architecture. With conditional branching, arithmetic, and memory access, it is fully Turing-complete. Its unique 529-byte memory (23²) and 4-trivigit words make it an elegant pedagogical model for non-binary computing.

See Also

Categories