summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-01-10 15:58:09 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2020-01-10 15:58:09 -0500
commit3344c607e7c639f894d5acce39c5eb4413e35047 (patch)
tree568d1dba8bb0187340af952ef190406aa7391dc3
Finished the Sux Base ISA.
-rw-r--r--Makefile11
-rw-r--r--base-isa.ms264
-rw-r--r--base-op-desc.ms723
-rw-r--r--base-op-table.ms50
-rw-r--r--intro.ms202
-rw-r--r--surp.ms25
-rw-r--r--sux-cover.ms12
-rw-r--r--sux-spec.ms15
8 files changed, 1302 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b1cac3b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+OBJ = sux-spec.pdf
+COVER = sux-cover.ms
+SRC = sux-spec.ms
+
+all: clean sux.pdf
+
+sux.pdf: sux-spec.ms
+ soelim $(SRC) | dformat.awk | pdfroff --stylesheet=$(COVER) -tp -mspdf - --pdf-output=$(OBJ)
+
+clean:
+ rm -f $(OBJ)
diff --git a/base-isa.ms b/base-isa.ms
new file mode 100644
index 0000000..6ec9513
--- /dev/null
+++ b/base-isa.ms
@@ -0,0 +1,264 @@
+.\" Start of the Base ISA.
+.NH
+.XN The Sux Base Instruction Set, Version 1.0
+.LP
+This chapter describes version 1.0 of the Sux base instruction set.
+.bp +1
+.\" Start of the programmers' model.
+.NH 2
+.XN Programmers' Model for the Base ISA
+.LP
+Figure 2 Shows the state for the base ISA. The base ISA only has
+four registers, each of which are 64 bits in size, each register
+has a special property, but can be still be used like general
+purpose registers.
+.LP
+The accumulator, or A is the main register of the base ISA,
+and is used for all ALU based instructions. the B register
+is a secondary ALU register, and can be used in place of a
+memory address for all ALU instructions, the X register is
+a register that can be used for indexing, but has a special
+property, as it is the only register that can set the stack
+pointer, and finally, the Y register, like the X register
+can be used for indexing, both normal, and pointer based.
+.begin dformat
+style bitwid .04
+style recht .1618033
+style recspread 0
+noname
+ 63-0-64 A
+noname
+ 63-0-64 B
+noname
+ 63-0-64 X
+noname
+ 63-0-64 Y
+.end
+.ce
+Figure 2: Sux base register state.
+.\" End of the programmers' model.
+.
+.bp +1
+.\" Start of instruction format.
+.NH 2
+.XN Base Instruction Format
+.LP
+The base Sux ISA has variable length instructions ranging
+from a single byte, to as many as 10 bytes, and are always
+byte aligned. The base ISA is also little endian, with no
+possiblity for bi-endian setups.
+.LP
+The reasoning for why we chose little endian, was because it
+is much simpler to work with, plus, it is very easy to understand,
+and is very intuitive.
+.LP
+The high code density is achived by using a prefix byte,
+which is not part of the instruction, but rather tells
+the CPU extra information like, how many bytes to read/write,
+whether it should use 8/16 bit addresses, or 32/64 bit addresses,
+or what instruction set extension it should use.
+.LP
+The base ISA is made up of 198 total opcodes, comprised of
+93 instructions. All of the opcodes are one byte in length.
+The max operand count for the base ISA is one. These might
+look like typos, but all of them were done on purpose, both
+in order to make the base ISA easier to understand, and to
+keep the opcode length at one byte.
+.LP
+The instruction formatting for the Sux base ISA is shown in Figure 2.1.
+.begin dformat
+style bitwid .08
+style recht .3
+style recspread 0
+noname
+ 71-40-32 opr[63:32]
+ 39-24-16 opr[31:16]
+ 23-16-8 opr[15:8]
+ 15-8-8 opr[7:0]
+ 7-0-8 opcode
+ 7-0-8-dashed prefix
+.end
+Figure 2.1: Sux base instruction format. There are subfields
+for the operand because the prefix byte can specify the size
+of the operand, from 8 bits, all the way up to 64 bits.
+.LP
+The processor status register, is a register that contains
+flags for use with conditional branches, Figure 2.2 shows
+the layout of these flags, the processor status register
+is 64 bits in size, but only eight bits are used, this is
+so that we can have upto eight sets of these flags, and
+make conditional branching with threads, much easier.
+.LP
+The Carry flag, or C denotes when a register has carried over.
+The Zero flag, or Z denotes when a register is zero.
+The Interrupt flag, or I is used to disable/enable
+maskable interrupts, when set, it disables interrupts,
+when cleared, it enables interrupts.
+The Stack protection flag, or S is used to prevent stack
+overflows, and stack underflows, by not incrementing, or
+decrementing if the stack pointer is at it's lowest value,
+or it's highest value.
+The Overflow flag, or V denotes whenever an overflow of a
+register occurs.
+And the Negative flag, or N is used to denote a negative
+value, and allows the use of signed integers.
+.begin dformat
+style bitwid .5
+style recspread 0
+noname
+ 7-7-1 N
+ 6-6-1 V
+ --1
+ --1
+ 3-3-1 S
+ 2-2-1 I
+ 1-1-1 Z
+ 0-0-1 C
+.end
+.ce
+Figure 2.2: The flags of the Processor status register.
+.\" End of instruction format
+.
+.bp +1
+.\" Start of instruction opcodes.
+.NH 2
+.XN Base Instruction Opcodes
+.LP
+This section describes each of the instructions, for the Sux base
+ISA, and provides a table, listing the opcodes for every instruction.
+.so base-op-table.ms
+.bp +1
+.so base-op-desc.ms
+.\" End of instruction opcodes.
+.
+.bp +1
+.\" Start of the prefix byte.
+.NH 2
+.XN The Prefix Byte
+.LP
+As mentioned before, there is a prefix byte. The prefix byte
+is a byte that occurs before the opcode, and gives the CPU
+more control over things like, the number of bytes that it will
+read/write, switching between 8/16 bit addressing, and 32/64 bit
+addressing, and switching between different instruction set extensions.
+.LP
+Figure 2.3 shows the layout of the prefix byte.
+.br
+Table 2 explains what the prefix bits do.
+.begin dformat
+style bitwid .5
+style recspread 0
+noname
+ 7-7-1 EX1
+ 6-6-1 EX0
+ 5-5-1 RS1
+ 4-4-1 RS0
+ 3-3-1 AM
+ 2-2-1 1
+ 1-1-1 1
+ 0-0-1 1
+.end
+.ce
+Figure 2.3: The control bits of the prefix byte.
+
+.ce
+Table 2. Description of the prefix bits
+.TS
+center tab(;) allbox;
+lb lb
+l l
+l l
+lb lb
+l l
+l l
+l l
+l l
+lb lb
+l l
+l l
+l l
+l l.
+AM;Addressing Modes
+0;Normal Addressing Modes (8/16 bit)
+1;Extended Addressing Modes (32/64 bit)
+RS1/RS0;Register Size
+0/0;8 bit register
+0/1;16 bit register
+1/0;32 bit register
+1/1;64 bit register
+EX1/EX0;Extension Selection
+0/0;Base ISA
+0/1;GFsuX Graphics Oriented Extension
+1/0;Unused
+1/1;\[*m]DCROM
+.TE
+
+.LP
+If no prefix byte is found, then it treats that byte as an
+opcode, and acts as if it had a prefix byte, with all the
+prefix bits set to 0.
+.\" End of the prefix byte.
+.
+.bp +1
+.\" Start of assembly syntax.
+.NH 2
+.XN Assembly Language Syntax for the Sux Base ISA
+.LP
+The syntax of Sux assembly, was designed to be simple,
+and very easy to understand. The syntax looks like this.
+.ce
+ADC.W #$1000
+This is what it means.
+.TS
+tab(;) allbox;
+lb l.
+ADC;Instruction
+\.W;Register Size Suffix
+#$1000;Operand
+.TE
+.LP
+For the Register Size Suffixes, there are four options.
+.TS
+tab(;) allbox;
+lb l.
+None;One byte (8 bits)
+\.W/\.2;Two bytes (16 bits)
+\.D/\.4;Four bytes (32 bits)
+\.Q/\.8;Eight bytes (64 bits)
+.TE
+.LP
+These Suffixes control the prefix byte. If there is no suffix,
+then it will not place a prefix byte, saving a byte.
+.LP
+The operand can be a few things.
+.TS
+tab(;) allbox;
+lb lb
+l l.
+Syntax;Description
+Value;Decimal Address
+$<Value>;Hexadecimal Address
+%<Value>;Binary Address
+#[token]<Value>;Immediate Data Value
+[token]<Value>, <X/Y>;Zero Matrix, Indexed with X, or Y
+([token]<Value>);Indirect Addressing
+([token]<Value>, X);Indexed Indirect Addressing
+([token]<Value>), Y;Indirect Indexed Addressing
+.TE
+.\" End of assembly syntax.
+.
+.bp +1
+.\" Start of the MicroDeCodeROM.
+.NH 2
+.XN The \[*m]DCROM
+.LP
+The \[*m]DCROM is a type of Programmable Logic Array (PLA) that has each of it's interconnects
+connected to an SRAM bit. This SRAM can then be accessed just like any other part of memory,
+and as such, is fully reprogrammable by the user.
+.LP
+The starting location of the \[*m]DCROM, is value located at the \[*m]DCROM vector.
+.LP
+The byte before the start of the \[*m]DCROM is the control byte, which is used
+to specify how the \[*m]DCROM should be accessed.
+.\" End of the MicroDeCodeROM.
+.\" End of the Base ISA.
diff --git a/base-op-desc.ms b/base-op-desc.ms
new file mode 100644
index 0000000..9110b25
--- /dev/null
+++ b/base-op-desc.ms
@@ -0,0 +1,723 @@
+.NH 3
+.XN Descriptions for each instruction of the Sux Base ISA
+.LP
+.tl 'CPS''Clear Processor Status register.'
+.tl 'Opcode''$00'
+.LP
+The CPS instruction clears all 64 bits of the processor status register.
+
+.LP
+.tl 'ADC''ADd with Carry.'
+.tl 'Opcodes''#=$01 a=$03 zm=$05'
+.tl 'Flags''N V Z C'
+.LP
+The ADC instruction adds the operand with the accumulator, and then
+stores it back into the accumulator. If the carry flag is set, then
+it adds the carry flag along with the sum.
+
+.LP
+.tl 'AAB''Add Accumulator, and B with carry.'
+.tl 'Opcode''$02'
+.tl 'Flags''N V Z C'
+.LP
+The AAB instruction is just like the ADC instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'PHB''PusH the B register.'
+.tl 'Opcode''$06'
+.LP
+The PHB instruction pushes the number of bytes specified, from the B
+register, onto the stack.
+
+.LP
+.tl 'PHP''PusH the Processor status register.'
+.tl 'Opcode''$08'
+.LP
+The PHP instruction pushes the number of bytes specified, from the
+processor status register, onto the stack.
+
+.LP
+.tl 'LDA''LoaD Accumulator.'
+.tl 'Opcodes''#=$09 a=$19 zm=$39 zmx=$59 zmy=$79 ind=$99 inx=$B9 iny=$D9'
+.tl 'Flags''N Z '
+.LP
+The LDA instruction loads the value from the operand, into the Accumulator.
+It also sets the N, and Z flags.
+
+.LP
+.tl 'LDY''LoaD value into Y register.'
+.tl 'Opcodes''#=$0A a=$1A zm=$3A zmx=$5A ind=$7A inx=$9A'
+.tl 'Flags''N Z '
+.LP
+The LDY instruction loads the value from the operand, into the Y register.
+It also sets the N, and Z flags.
+
+.LP
+.tl 'LDX''LoaD value into X register.'
+.tl 'Opcodes''#=$0B a=$1B zm=$3B zmx=$5B ind=$7B inx=$9B'
+.tl 'Flags''N Z '
+.LP
+The LDX instruction loads the value from the operand, into the X register.
+It also sets the N, and Z flags.
+
+.LP
+.tl 'TAB''Transfer value from the Accumulator, to the B register.'
+.tl 'Opcode''$0C'
+.tl 'Flags''N Z '
+.LP
+The TAB instruction transfers the value that is in the Accumulator, to the
+B register. It also sets the N, and Z flags.
+.bp +1
+.LP
+.tl 'LDB''LoaD value into B register.'
+.tl 'Opcodes''#=$0E a=$1E zm=$3E zmx=$5E zmy=$7E ind=$9E inx=$BE iny=$DE'
+.tl 'Flags''N Z '
+.LP
+The LDB instruction loads the value from the operand, into the B register.
+It also sets the N, and Z flags.
+
+.LP
+.tl 'JMP''JuMP to memory address.'
+.tl 'Opcodes''a=$10 zm=$D0 ind=$04 inx=$14 iny=$24'
+.LP
+The JMP instruction sets the program counter to the address, specified by
+the operand.
+
+.LP
+.tl 'SBC''SuBtract with Carry.'
+.tl 'Opcodes''#=$11 a=$13 zm=$15'
+.tl 'Flags''N V Z C'
+.LP
+The SBC instruction subtracts the operand with the accumulator, and then
+stores the result back into the accumulator. If the carry flag is set,
+then it borrows from the carry flag along with the sum.
+
+.LP
+.tl 'SAB''Subtract Accumulator, and B with carry.'
+.tl 'Opcode''$12'
+.tl 'Flags''N V Z C'
+.LP
+The SAB instruction is just like the SBC instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'PLB''PuLl value from the stack, into the B register.'
+.tl 'Opcode''$16'
+.LP
+The PLB instruction pulls/pops the number of bytes specified, off the
+stack, and into the B register.
+
+.LP
+.tl 'PLP''PuLl value from the stack, into the Processor status register.'
+.tl 'Opcode''$18'
+.LP
+The PLB instruction pulls/pops the number of bytes specified, off the
+stack, and into the Processor status register.
+
+.LP
+.tl 'TBA''Transfer value from the B register to the Accumulator.'
+.tl 'Opcode''$1C'
+.tl 'Flags''N Z '
+.LP
+The TBA instruction transfers the value that is in the B register, to the
+Accumulator. It also sets the N, and Z flags.
+
+.LP
+.tl 'JSR''Jump to SubRoutine.'
+.tl 'Opcodes''zm=$20 ind=$34 inx=$44 iny=$54'
+.LP
+The JSR instruction pushes the current value of the program counter, onto
+the stack, and then sets the program counter to the address, specified by
+the operand.
+
+.LP
+.tl 'AND''bitwise AND accumulator.'
+.tl 'Opcodes''#=$21 a=$23 zm=$25'
+.tl 'Flags''N Z '
+.LP
+The AND instruction takes an operand, and ANDs it with the accumulator,
+then saves the results back into the accumulator.
+.bp +1
+.LP
+.tl 'ABA''bitwise And Accumulator, with the B register.'
+.tl 'Opcode''$22'
+.tl 'Flags''N Z '
+.LP
+The ABA instruction is just like the AND instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'CPB''ComPare the B register, with an operand.'
+.tl 'Opcodes''#=$26 a=$36 zm=$46 ind=$56 inx=$66 iny=$76'
+.tl 'Flags''N V Z C'
+.LP
+The CPB instruction compares the value in the B register, with an operand,
+and sets the flags accordingly. It compares the two values by subtracting
+them.
+
+.LP
+.tl 'STT''STart a Thread.'
+.tl 'Opcode''$28'
+.LP
+The STT instruction, sets the current running threads register, and
+then has the threads read their thread vector. The current running
+threads register is an 8 bit register, that states which threads
+are running currently, the first 7 bits of the register states
+which of the 7 other threads are running, the remaining 16 bits
+of the operand, if specified, are used to tell the instruction
+which core to start, and are read bytewise, rather than bitwise.
+This instruction will not be implemented, if the core
+count, and thread count are both 1, otherwise, it will.
+
+.LP
+.tl 'STA''STore the Accumulator, into memory.'
+.tl 'Opcodes''a=$29 zm=$49 zmx=$69 zmy=$89 ind=$A9 inx=$C9 iny=$E9'
+.LP
+The STA instruction writes the value of the Accumulator, into a memory
+address.
+
+.LP
+.tl 'STY''STore the Y register, into memory.'
+.tl 'Opcodes''a=$2A zm=$4A zmx=$6A ind=$8A inx=$AA'
+.LP
+The STY instruction writes the value of the Y register, into a memory
+address.
+
+.LP
+.tl 'STX''STore the X register, into memory.'
+.tl 'Opcodes''a=$2B zm=$4B zmx=$6B ind=$8B inx=$AB'
+.LP
+The STX instruction writes the value of the X register, into a memory
+address.
+
+.LP
+.tl 'TAY''Transfer value from the Accumulator, to the Y register.'
+.tl 'Opcode''$2C'
+.tl 'Flags''N Z '
+.LP
+The TAY instruction transfers the value that is in the Accumulator, to the
+Y register. It also sets the N, and Z flags.
+
+.LP
+.tl 'STB''STore the B register, into memory.'
+.tl 'Opcodes''a=$2E zm=$4E zmx=$6E zmy=$8E ind=$AE inx=$CE iny=$EE'
+.LP
+The STB instruction writes the value of the B register, into a memory
+address.
+
+.LP
+.tl 'BPO''Branch if POsitive.'
+.tl 'Opcodes''a=$30 zm=$64'
+.LP
+The BPO instruction will branch, if the Negative flag is cleared.
+.bp +1
+.LP
+.tl 'ORA''bitwise OR Accumulator.'
+.tl 'Opcodes''#=$31 a=$33 zm=$35'
+.tl 'Flags''N Z '
+.LP
+The ORA instruction takes an operand, and ORs it with the accumulator,
+then saves the results back into the accumulator.
+
+.LP
+.tl 'OAB''bitwise Or Accumulator, with the B register.'
+.tl 'Opcode''$32'
+.tl 'Flags''N Z '
+.LP
+The OAB instruction is just like the ORA instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'SEI''SEt the Interrupt flag.'
+.tl 'Opcode''$38'
+.tl 'Flags'' I '
+.LP
+The SEI instruction, sets the Interrupt flag, and thus disabling
+maskable interrupts.
+
+.LP
+.tl 'TYA''Transfer value from the Y register to the Accumulator.'
+.tl 'Opcode''$3C'
+.tl 'Flags''N Z '
+.LP
+The TYA instruction transfers the value that is in the Y register, to the
+Accumulator. It also sets the N, and Z flags.
+
+.LP
+.tl 'BNG''Branch if NeGative.'
+.tl 'Opcodes''a=$40 zm=$74'
+.LP
+The BNG instruction will branch, if the Negative flag is set.
+
+.LP
+.tl 'XOR''bitwise XOR accumulator.'
+.tl 'Opcodes''#=$41 a=$43 zm=$45'
+.tl 'Flags''N Z '
+.LP
+The XOR instruction takes an operand, and XORs it with the accumulator,
+then saves the results back into the accumulator.
+
+.LP
+.tl 'XAB''bitwise Xor Accumulator, with the B register.'
+.tl 'Opcode''$42'
+.tl 'Flags''N Z '
+.LP
+The XAB instruction is just like the XOR instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'CLI''CLear the Interrupt flag.'
+.tl 'Opcode''$48'
+.tl 'Flags'' I '
+.LP
+The CLI instruction, clears the Interrupt flag, and thus enabling
+maskable interrupts.
+
+.LP
+.tl 'TAX''Transfer value from the Accumulator to the X register.'
+.tl 'Opcode''$4C'
+.tl 'Flags''N Z '
+.LP
+The TAX instruction transfers the value that is in the Accumulator, to the
+X register. It also sets the N, and Z flags.
+
+.LP
+.tl 'BCS''Branch if Carry Set.'
+.tl 'Opcodes''a=$50 zm=$84'
+.LP
+The BCS instruction will branch, if the Carry flag is set.
+
+.LP
+.tl 'LSL''Logical Shift Left accumulator.'
+.tl 'Opcodes''#=$51 a=$53 zm=$55'
+.tl 'Flags''N Z C'
+.LP
+The LSL instruction takes an operand, and shifts the accumulator left by
+the number of bits from the operand, then saves the results back into the
+accumulator. The Carry flag is set whenever a one is shifted out of the
+accumulator.
+
+.LP
+.tl 'LLB''Logical shift Left accumulator, with the B register.'
+.tl 'Opcode''$52'
+.tl 'Flags''N Z C'
+.LP
+The LLB instruction is just like the LSL instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'SEC''SEt the Carry flag.'
+.tl 'Opcode''$58'
+.tl 'Flags'' C'
+.LP
+The SEC instruction, sets the Carry flag.
+
+.LP
+.tl 'TXA''Transfer value from the X register to the Accumulator.'
+.tl 'Opcode''$5C'
+.tl 'Flags''N Z '
+.LP
+The TXA instruction transfers the value that is in the X register, to the
+Accumulator. It also sets the N, and Z flags.
+
+.LP
+.tl 'BCC''Branch if Carry Clear.'
+.tl 'Opcodes''a=$60 zm=$94'
+.LP
+The BCC instruction will branch, if the Carry flag is cleared.
+
+.LP
+.tl 'LSR''Logical Shift Right accumulator.'
+.tl 'Opcodes''#=$61 a=$63 zm=$65'
+.tl 'Flags''N Z C'
+.LP
+The LSR instruction takes an operand, and shifts the accumulator right by
+the number of bits from the operand, then saves the results back into the
+accumulator. The Carry flag is set whenever a one is shifted out of the
+accumulator.
+
+.LP
+.tl 'LRB''Logical shift Right accumulator, with the B register.'
+.tl 'Opcode''$62'
+.tl 'Flags''N Z C'
+.LP
+The LRB instruction is just like the LSR instruction, except that
+it uses the B register as an operand, rather than memory.
+.bp +1
+.LP
+.tl 'CLC''CLear the Carry flag.'
+.tl 'Opcode''$68'
+.tl 'Flags'' C'
+.LP
+The CLC instruction, clears the Carry flag.
+
+.LP
+.tl 'TYX''Transfer value from the Y register to the X register.'
+.tl 'Opcode''$6C'
+.tl 'Flags''N Z '
+.LP
+The TYX instruction transfers the value that is in the Y register, to the
+X register. It also sets the N, and Z flags.
+
+.LP
+.tl 'BEQ''Branch if EQual.'
+.tl 'Opcodes''a=$70 zm=$A4'
+.LP
+The BEQ instruction will branch, if the Zero flag is set.
+
+.LP
+.tl 'ROL''ROtate Left accumulator.'
+.tl 'Opcodes''#=$71 a=$73 zm=$75'
+.tl 'Flags''N Z C'
+.LP
+The ROL instruction takes an operand, and rotates the accumulator left by
+the number of bits from the operand, then saves the results back into the
+accumulator. The Carry flag is set whenever a one is shifted out of the
+accumulator.
+
+.LP
+.tl 'RLB''Rotate Left accumulator, with the B register.'
+.tl 'Opcode''$72'
+.tl 'Flags''N Z C'
+.LP
+The RLB instruction is just like the ROL instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'SSP''Set the Stack Protection flag.'
+.tl 'Opcode''$78'
+.tl 'Flags'' S '
+.LP
+The SSP instruction, sets the Stack protection flag.
+
+.LP
+.tl 'TXY''Transfer value from the X register to the Y register.'
+.tl 'Opcode''$7C'
+.tl 'Flags''N Z '
+.LP
+The TXY instruction transfers the value that is in the X register, to the
+Y register. It also sets the N, and Z flags.
+.bp +1
+.LP
+.tl 'BNE''Branch if Not Equal.'
+.tl 'Opcodes''a=$80 zm=$B4'
+.LP
+The BNE instruction will branch, if the Zero flag is cleared.
+
+.LP
+.tl 'ROR''ROtate Right accumulator.'
+.tl 'Opcodes''#=$81 a=$83 zm=$85'
+.tl 'Flags''N Z C'
+.LP
+The ROR instruction takes an operand, and rotates the accumulator right by
+the number of bits from the operand, then saves the results back into the
+accumulator. The Carry flag is set whenever a one is shifted out of the
+accumulator.
+
+.LP
+.tl 'RRB''Rotate Right accumulator, with the B register.'
+.tl 'Opcode''$82'
+.tl 'Flags''N Z C'
+.LP
+The RRB instruction is just like the ROR instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'INY''INcrement the Y register.'
+.tl 'Opcode''$86'
+.tl 'Flags''N Z '
+.LP
+The INY instruction increments the Y register.
+
+.LP
+.tl 'CSP''Clear the Stack Protection flag.'
+.tl 'Opcode''$88'
+.tl 'Flags'' S '
+.LP
+The CSP instruction, clears the Stack protection flag.
+
+.LP
+.tl 'TSX''Transfer value from the Stack pointer to the X register.'
+.tl 'Opcode''$8C'
+.tl 'Flags''N Z '
+.LP
+The TSX instruction transfers the value that is in the Stack pointer, to the
+X register. It also sets the N, and Z flags.
+
+.LP
+.tl 'BVS''Branch if oVerflow Set.'
+.tl 'Opcodes''a=$90 zm=$C4'
+.LP
+The BVS instruction will branch, if the Overflow flag is set.
+
+.LP
+.tl 'MUL''MULtiply accumulator, by operand.'
+.tl 'Opcodes''#=$91 a=$93 zm=$95'
+.tl 'Flags''N V Z C'
+.LP
+The MUL instruction takes an operand, and multiplys the accumulator by the
+operand, then saves the results back into the accumulator. If the Carry flag
+is set, then it will add one to the result.
+
+.LP
+.tl 'MAB''Multiply Accumulator, with the B register.'
+.tl 'Opcode''$92'
+.tl 'Flags''N V Z C'
+.LP
+The MAB instruction is just like the MUL instruction, except that
+it uses the B register as an operand, rather than memory.
+.bp +1
+.LP
+.tl 'DEY''DEcrement the Y register.'
+.tl 'Opcode''$96'
+.tl 'Flags''N Z '
+.LP
+The DEY instruction decrements the Y register.
+
+.LP
+.tl 'SEV''SEt the oVerflow flag.'
+.tl 'Opcode''$98'
+.tl 'Flags'' V '
+.LP
+The SEV instruction, sets the Overflow flag.
+.LP
+.tl 'TXS''Transfer value from the X register to the Stack pointer.'
+.tl 'Opcode''$9C'
+.tl 'Flags''N Z '
+.LP
+The TXS instruction transfers the value that is in the X register, to the
+Stack pointer, if the prefix byte has a high nibble of $1, then it will turn
+into an immediate data instruction, and the operand will set the Stack Bank
+Register, the SBR is a 16 bit register that states where the starting address
+of the Stack pointer is. It also sets the N, and Z flags.
+
+.LP
+.tl 'BVC''Branch if oVerflow Clear.'
+.tl 'Opcodes''a=$A0 zm=$D4'
+.LP
+The BVC instruction will branch, if the Overflow flag is cleared.
+
+.LP
+.tl 'DIV''DIVide accumulator, by operand.'
+.tl 'Opcodes''#=$A1 a=$A3 zm=$A5'
+.tl 'Flags''N V Z '
+.LP
+The DIV instruction takes an operand, and divides the accumulator by the
+operand, then saves the results back into the accumulator.
+
+.LP
+.tl 'DAB''Divide Accumulator, with the B register.'
+.tl 'Opcode''$A2'
+.tl 'Flags''N V Z '
+.LP
+The DAB instruction is just like the DIV instruction, except that
+it uses the B register as an operand, rather than memory. It also
+let's you dab on all those lesser ISAs.
+
+.LP
+.tl 'INX''INcrement the X register.'
+.tl 'Opcode''$A6'
+.tl 'Flags''N Z '
+.LP
+The INX instruction increments the X register.
+
+.LP
+.tl 'CLV''CLear the oVerflow flag.'
+.tl 'Opcode''$A8'
+.tl 'Flags'' V '
+.LP
+The CLV instruction, clears the Overflow flag.
+
+.LP
+.tl 'PHY''PusH the Y register.'
+.tl 'Opcode''$AC'
+.LP
+The PHY instruction pushes the number of bytes specified, from the Y
+register, onto the stack.
+
+.LP
+.tl 'RTS''ReTurn from Subroutine.'
+.tl 'Opcodes''$B0'
+.LP
+The RTS instruction is the opposite of the JSR instruction,
+in that it pulls from the stack, the address that JSR had pushed,
+and places it in the program counter.
+
+.LP
+.tl 'CMP''CoMPare accumulator, with operand.'
+.tl 'Opcodes''#=$B1 a=$B3 zm=$B5 ind=$F1 inx=$F3 iny=$F5'
+.tl 'Flags''N V Z C'
+.LP
+The CMP instruction compares the value in the B register, with an operand,
+and sets the flags accordingly. It compares the two values by subtracting
+them.
+
+.LP
+.tl 'CAB''Compare Accumulator, with the B register.'
+.tl 'Opcode''$B2'
+.tl 'Flags''N V Z C'
+.LP
+The CAB instruction is just like the CMP instruction, except that
+it uses the B register as an operand, rather than memory.
+
+.LP
+.tl 'DEX''DEcrement the X register.'
+.tl 'Opcode''$B6'
+.tl 'Flags''N Z '
+.LP
+The DEX instruction decrements the X register.
+
+.LP
+.tl 'ENT''ENd a Thread.'
+.tl 'Opcode''$B8'
+.LP
+The ENT instruction, clears the bits in the Current Running Threads register,
+specified by the operand.
+
+.LP
+.tl 'CPY''ComPare the B register, with an operand.'
+.tl 'Opcodes''#=$BA a=$CA zm=$DA ind=$EA inx=$FA'
+.tl 'Flags''N V Z C'
+.LP
+The CPY instruction compares the value in the Y register, with an operand,
+and sets the flags accordingly. It compares the two values by subtracting
+them.
+
+.LP
+.tl 'CPX''ComPare the X register, with an operand.'
+.tl 'Opcodes''#=$BB a=$CB zm=$DB ind=$EB inx=$FB'
+.tl 'Flags''N V Z C'
+.LP
+The CPX instruction compares the value in the X register, with an operand,
+and sets the flags accordingly. It compares the two values by subtracting
+them.
+
+.LP
+.tl 'PLY''PuLl value from the stack, into the Y register.'
+.tl 'Opcode''$BC'
+.LP
+The PLY instruction pulls/pops the number of bytes specified, off the
+stack, and into the Y register.
+
+.LP
+.tl 'RTI''ReTurn from Interrupt.'
+.tl 'Opcodes''$C0'
+.LP
+The RTI instruction is like the RTS instruction, in that it pulls from the stack,
+the previous value of the processor status register, and the previous address that
+had been pushed from an interrupt, and places them into, the processor status register,
+and the program counter, respectivly.
+.bp +1
+.LP
+.tl 'INC''INCrement accumulator, or memory address.'
+.tl 'Opcodes''A=$C1 a=$C3 zm=$C5'
+.tl 'Flags''N Z '
+.LP
+The INC instruction increments either the accumulator, or the contents of a
+memory address.
+
+.LP
+.tl 'IAB''Increment Accumulator, with the B register.'
+.tl 'Opcode''$C2'
+.tl 'Flags''N Z '
+.LP
+The IAB instruction increments both the accumulator, and the B register.
+
+.LP
+.tl 'WAI''WAIt for an interrupt.'
+.tl 'Opcode''$C8'
+.LP
+The WAI instruction, puts the CPU into a sleep mode, where it is only
+awake enough to be able to respond to an interrupt, and as such, not only
+uses less power, but also allows for very fast interrupt response times.
+
+.LP
+.tl 'PHX''PusH the X register.'
+.tl 'Opcode''$CC'
+.LP
+The PHX instruction pushes the number of bytes specified, from the X
+register, onto the stack.
+
+.LP
+.tl 'DEC''DECrement accumulator, or memory address.'
+.tl 'Opcodes''A=$D1 a=$D3 zm=$D5'
+.tl 'Flags''N Z '
+.LP
+The DEC instruction decrements either the accumulator, or the contents of a
+memory address.
+
+.LP
+.tl 'DBA''Dncrement Accumulator, with the B register.'
+.tl 'Opcode''$D2'
+.tl 'Flags''N Z '
+.LP
+The DBA instruction decrements both the accumulator, and the B register.
+
+.LP
+.tl 'PLX''PuLl value from the stack, into the X register.'
+.tl 'Opcode''$DC'
+.LP
+The PLX instruction pulls/pops the number of bytes specified, off the
+stack, and into the X register.
+
+.LP
+.tl 'JSL''Jump to Subroutine, Long addressing.'
+.tl 'Opcode''a=$E0'
+.LP
+The JSL instruction, is just like the JSR instruction, except that it pushes
+a 64 bit address onto the stack.
+
+.LP
+.tl 'ASR''Arithmetic Shift Right accumulator.'
+.tl 'Opcodes''#=$E1 a=$E3 zm=$E5'
+.tl 'Flags''N Z C'
+.LP
+The ASR instruction takes an operand, and shifts the accumulator right by
+the number of bits from the operand, then saves the results back into the
+accumulator. But unlike LSR, ASR shifts in the sign bit into the accumulator.
+The Carry flag is set whenever a one is shifted out of the accumulator.
+
+.LP
+.tl 'ARB''Arithmetic shift Right accumulator, with the B register.'
+.tl 'Opcode''$E2'
+.tl 'Flags''N Z C'
+.LP
+The ARB instruction is just like the ASR instruction, except that
+it uses the B register as an operand, rather than memory.
+.bp +1
+.LP
+.tl 'NOP''No OPeration.'
+.tl 'Opcode''$E8'
+.LP
+The NOP instruction does what you think it does, it does nothing at all.
+
+.LP
+.tl 'PHA''PusH the Accumulator.'
+.tl 'Opcode''$EC'
+.LP
+The PHA instruction pushes the number of bytes specified, from the
+Accumulator, onto the stack.
+
+.LP
+.tl 'RTL''ReTurn from subroutine, Long addressing.'
+.tl 'Opcodes''$F0'
+.LP
+The RTL instruction, is just like the RTS instruction, except that it pulls
+a 64 bit address from the stack.
+
+.LP
+.tl 'BRK''BReaKpoint.'
+.tl 'Opcode''$F8'
+.LP
+The BRK instruction triggers a software interrupt, which pushes the value
+in the processor status register, and the address in the program counter,
+onto the stack, then reads the BRK vector, and then jumps to the address
+located there.
+
+.LP
+.tl 'PLA''PuLl value from the stack, into the Accumulator.'
+.tl 'Opcode''$FC'
+.LP
+The PLA instruction pulls/pops the number of bytes specified, off the
+stack, and into the accumulator.
diff --git a/base-op-table.ms b/base-op-table.ms
new file mode 100644
index 0000000..0420c35
--- /dev/null
+++ b/base-op-table.ms
@@ -0,0 +1,50 @@
+.ce
+Table 1. Sux base opcode table
+.ps -4.25
+.TS
+center tab(;) allbox;
+l cb cb cb cb cb cb cb cb cb cb cb cb cb cb cb cb
+cb c c c c c c c c c c c c c c c.
+;x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;xA;xB;xC;xD;xE;xF
+0x;CPS;ADC #;AAB;ADC a;JMP ind;ADC zm;PHB;;PHP;LDA #;LDY #;LDX #;TAB;;LDB #;
+1x;JMP a;SBC #;SAB;SBC a;JMP inx;SBC zm;PLB;;PLP;LDA a;LDY a;LDX a;TBA;;LDB a;
+2x;JSR;AND #;ABA;AND a;JMP iny;AND zm;CPB #;;STT;STA a;STY a;STX a;TAY;;STB a;
+3x;BPO;ORA #;OAB;ORA a;JSR ind;ORA zm;CPB a;;SEI;LDA zm;LDY zm;LDX zm;TYA;;LDB zm;
+4x;BNG;XOR #;XAB;XOR a;JSR inx;XOR zm;CPB zm;;CLI;STA zm;STY zm;STX zm;TAX;;STB zm;
+5x;BCS;LSL #;LLB;LSL a;JSR iny;LSL zm;CPB ind;;SEC;LDA zmx;LDY zmx;LDX zmy;TXA;;LDB zmx;
+6x;BCC;LSR #;LRB;LSR a;BPO zm;LSR zm;CPB inx;;CLC;STA zmx;STY zmx;STX zmy;TYX;;STB zmx;
+7x;BEQ;ROL #;RLB;ROL a;BNG zm;ROL zm;CPB iny;;SSP;LDA zmy;LDY ind;LDX ind;TXY;;LDB zmy;
+8x;BNE;ROR #;RRB;ROR a;BCS zm;ROR zm;INY;;CSP;STA zmy;STY ind;STX ind;TSX;;STB zmy;
+9x;BVS;MUL #;MAB;MUL a;BCC zm;MUL zm;DEY;;SEV;LDA ind;LDY inx;LDX iny;TXS;;LDB ind;
+Ax;BVC;DIV #;DAB;DIV a;BEQ zm;DIV zm;INX;;CLV;STA ind;STY inx;STX iny;PHY;;STB ind;
+Bx;RTS;CMP #;CAB;CMP a;BNE zm;CMP zm;DEX;;ENT;LDA inx;CPY #;CPX #;PLY;;LDB inx;
+Cx;RTI;INC A;IAB;INC a;BVS zm;INC zm;;;WAI;STA inx;CPY a;CPX a;PHX;;STB inx;
+Dx;JMP zm;DEC A;DBA;DEC a;BVC zm;DEC zm;;;;LDA iny;CPY zm;CPX zm;PLX;;LDB iny;
+Ex;JSL;ASR #;ARB;ASR a;;ASR zm;;;NOP;STA iny;CPY ind;CPX ind;PHA;;STB iny;
+Fx;RTL;CMP ind;;CMP inx;;CMP iny;;;BRK;;CPY inx;CPX iny;PLA;;;
+.TE
+.ps
+.LP
+"#" means Immediate data.
+.br
+"a" means Absolute addressing.
+.br
+"zm" means Zero Matrix, which refers to
+the first 4 GiB of the address space.
+.br
+"zmx" means Zero Matrix, indexed with the
+X register.
+.br
+"zmy" means Zero Matrix, indexed with the
+Y register.
+.br
+"ind" means Indirect addressing, Also known
+as pointer addressing.
+.br
+"inx" means Indexed Indirect addressing.
+.br
+"iny" means Indirect Indexed addressing.
+.br
+"A" means Accumulator.
+.br
+And no operand means implied addressing.
diff --git a/intro.ms b/intro.ms
new file mode 100644
index 0000000..dd12a16
--- /dev/null
+++ b/intro.ms
@@ -0,0 +1,202 @@
+\" Start of the introduction.
+.NH
+.XN Introduction
+.LP
+Sux
+(Pronounced "sucks")
+is a new, 64-bit CISC instruction-set architecture,
+(ISA)
+that was designed to be very simple,
+and easy to understand.
+Our goals in creating Sux include:
+.IP \[bu] 2
+A 100% totally free
+(as in freedom)
+ISA that both respects your freedoms,
+and does not allow anyone to make proprietary versions of it.
+.IP \[bu] 2
+An ISA that is suitable for implementing in hardware,
+not just emulation,
+or binary translation.
+.IP \[bu] 2
+An ISA that is very simple,
+both at the assembly language level,
+and at the hardware level.
+.IP \[bu] 2
+An ISA that can be implemented with as
+low a transistor count as possible,
+and therefore, very cheap to produce.
+.IP \[bu] 2
+An ISA that can actually be understood by any programmer,
+and is actually possible to write assembly language programs in.
+.IP \[bu] 2
+An ISA that is very memory efficient.
+.IP \[bu] 2
+An ISA that is extremely fast,
+and allows for an insane number of cores.
+.IP \[bu] 2
+An ISA that does not require uneeded bloat,
+just to make it "faster".
+.IP \[bu] 2
+An ISA that a hobbiest can use.
+.IP \[bu] 2
+An ISA that is easy to design a
+computer architecture arround.
+.FS
+We called the Instruction Set,
+Sux because it is meant to be very suckless,
+or suxless, although, that is not
+what Sux is short for.
+.FE
+.FS
+It was also named after a preposed x86 based CPU,
+which would have been called, Sux86less.
+.FE
+.FS
+It was never made because we deemed x86,
+too bloated for are purposes.
+.FE
+.FS
+It is also meant to be a joke on RISC-V,
+in the sense that, like RISC-V,
+Sux is small, and simple,
+but unlike RISC-V,
+Sux is more hobbiest oriented,
+rather than being more academic oriented.
+.FE
+.LP
+The Sux ISA does contain documentation for a reference platform,
+but the main details of the ISA are not specific to the reference platform.
+.\" End of the introduction.
+.
+.bp +1
+.\" Start of the terminolgy.
+.NH 2
+.XN Sux Hardware Platform Terminolgy
+.LP
+A Sux hardware platform can contain one,
+or more Sux compatible cores along with other supporting cores including,
+non-Sux compatible cores, MMUs, device controllers, and much more.
+.LP
+A component is dubbed a \fIcore\fP if it is a turing complete CPU.
+A Sux compatible core might support multiple threads, or diet cores,
+and are used in the same way as a standard core.
+.LP
+A Sux core might have have extra instruction set extensions, or a \fIcoprocessor\fP.
+We use the term \fIcoprocessor\fP to refer to any type of external device that
+offloads some processing from the main core.
+.LP
+The system-level organization of a Sux hardware platform can range from a single-core
+microcontroller, to a 128 core, 1024 thread CPU, or microcontroller, to a multi-CPU
+server node. But also even a system-on-a-chip configuration.
+.LP
+We'll be using both \fI$\fP to denote a hexadecimal
+value, and \fI%\fP to denote a binary value.
+.\" End of the terminolgy.
+.
+.bp +1
+.\" Start of the vectors.
+.NH 2
+.XN Sux Interrupt Vectors
+.LP
+The way execution is started in a Sux core, is very similar to older 8 bit ISAs,
+in that it uses vectors to denote where it should start executing code for some
+type of interrupt.
+.LP
+By default, if there are multiple Sux cores, and each core has multiple threads,
+it will start the first thread, of the first core, and then read one of those
+vectors.
+.LP
+Figure 1 shows the layout of the vectors for a Sux core.
+.TS
+tab(;) allbox;
+lb lb
+l l.
+Address;Name
+T{
+$FF50-$FF57
+.br
+$FF58-$FF5F
+.br
+$FF60-$FF67
+.br
+$FF60-$FF6F
+.br
+$FF70-$FF77
+.br
+$FF70-$FF7F
+.br
+$FF80-$FF87
+T};Thread Vector
+T{
+$FF90-$FF97
+T};\[*m]DCROM Vector
+T{
+$FFA0-FFA7
+T};IRQ Vector
+T{
+$FFC0-$FFC7
+T};Reset Vector
+T{
+$FFE0-FFE7
+T};BRK Vector
+.TE
+Figure 1: The vectors of Sux.
+
+.LP
+All Sux threads can have their execution be suspended by a
+wait-for-interrupt, or \fCWAI\fP instuction.
+.\" End of the vectors
+.
+.bp +1
+.\" Start of the overview.
+.NH 2
+.XN Sux ISA Overview
+.LP
+The Sux ISA is defined as a base integer ISA, which is required
+to be present in any implementation, plus any optional extensions to the base ISA.
+The base ISA is very similar to MOS Technology's 6502 ISA, except that it
+has a 64 bit data bus, 64 bit address bus, supports multiple threads,
+multiple cores, and much more.
+.LP
+Sux has been designed to make using external hardware, very easy to implement.
+Sux has also been designed to make customizing, very easy, by having a
+Microdecode ROM, or \[*m]DCROM for short. The \[*m]DCROM is covered in more detail
+later on.
+.LP
+Beyond the base ISA, we deem it unnecessary to add any extra opcodes, or
+insturctions to it, and as such, will be unchanged, from this point on.
+There will still be other extensions, but those will not be accessed in the
+manner as the base ISA.
+.\" End of the overview.
+.
+.bp +1
+.\" Start of the address space.
+.NH 2
+.XN Memory
+.LP
+A Sux thread has a byte-addressable address space of 2\*[{]64\*[}]
+bytes for all memory accesses. A \fIword\fP of memory is defined as
+16 bits (2 bytes), a \fIdoubleword\fP of memory is defined as
+32 bits (4 bytes), and a \fIquadword\fP of memory is defined as 64 bits (8 bytes).
+The address space is circular, so that the byte at address 2\*[{]64\*[}]-1
+is adjacent to the byte at address zero. Accordingly, memory address computations
+done by the hardware ignore overflow, and instead wrap arround modulo 2\*[{]64\*[}].
+.LP
+The mapping of hardware resources, is determined by the
+architecture of the hardware. These addresses may either
+(a) be open bus, (b) contain main memory, (c) be vacant,
+or (d) contain one, or more I/O devices. Reading, and writing
+to I/O devices may have visible side effects, but accessing
+main memory cannot. While you could have an architecture that
+only accesses I/O, it is usually expected that some of the
+address space will be main memory.
+.LP
+When a Sux platform has multiple threads, unless an MMU is used,
+the entire address space must be shared with all threads.
+.LP
+Executing each Sux machine instruction, most of the time
+requires one memory access, but sometimes it might require
+two memory accesses. These instructions are divided into
+multiple addressing modes.
+.\" End of the address space.
diff --git a/surp.ms b/surp.ms
new file mode 100644
index 0000000..c74dc55
--- /dev/null
+++ b/surp.ms
@@ -0,0 +1,25 @@
+.\" Start of SuRP, the Sux Reference Platform.
+.NH
+.XN The Sux Reference Platform
+.LP
+The Sux Reference Platform, or SuRP, is the reference architecture for
+Sux, and what most other architectures should be based on.
+.LP
+SuRP will have two boot firmwares, one called SuBAsm, or
+the Sux Bootstrapped Assembler, and a bootstrapped version
+of the Tiny C Compiler, called SuBTinyCC.
+.LP
+SuRP will have an MMU chip specifically designed for Sux, called the
+MinMMU, a PCI Express controller called MinPCIE, and an RS-232 controller
+called the Min232.
+.LP
+The reasoning for using an assembler, and a C compiler as boot firmware,
+was because we wanted to make sure that no one could run prorpietary
+code on any Sux based system, and to allow for a possible Maximite like
+computer, called the SuRPimite, which will use a microcontroller variant
+of Sux, called MicroSux.
+.LP
+MicroSux will come with SuBAsm, and SuBTinyCC built-in to the chip, but
+will still be on a flash chip, so that you can update it, but cannot be
+directly accessed by the user, and as such, will have a second flash for
+user programs.
diff --git a/sux-cover.ms b/sux-cover.ms
new file mode 100644
index 0000000..b5a1ae1
--- /dev/null
+++ b/sux-cover.ms
@@ -0,0 +1,12 @@
+.TL
+The Sux Instruction Set Manual
+.AU
+mr b0nk 500
+\F[C]b0nk@b0nk.xyz
+.AU
+Fraizeraust
+\F[C]fraizeraust99@gmail.com
+.AB no
+.AE
+.ce
+\F[T]\*[MONTH\n[mo]] \n[dy], \n[year]
diff --git a/sux-spec.ms b/sux-spec.ms
new file mode 100644
index 0000000..60e38d4
--- /dev/null
+++ b/sux-spec.ms
@@ -0,0 +1,15 @@
+.ig
+The Sux Instuction Set Manual.
+
+Written in troff, with the ms
+macro package.
+
+By mr b0nk 500 <b0nk@b0nk.xyz>
+..
+.bp +1
+.so intro.ms
+.bp +1
+.so base-isa.ms
+.bp +1
+.so surp.ms
+.TC