From 3344c607e7c639f894d5acce39c5eb4413e35047 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Fri, 10 Jan 2020 15:58:09 -0500 Subject: Finished the Sux Base ISA. --- Makefile | 11 + base-isa.ms | 264 ++++++++++++++++++++ base-op-desc.ms | 723 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ base-op-table.ms | 50 ++++ intro.ms | 202 ++++++++++++++++ surp.ms | 25 ++ sux-cover.ms | 12 + sux-spec.ms | 15 ++ 8 files changed, 1302 insertions(+) create mode 100644 Makefile create mode 100644 base-isa.ms create mode 100644 base-op-desc.ms create mode 100644 base-op-table.ms create mode 100644 intro.ms create mode 100644 surp.ms create mode 100644 sux-cover.ms create mode 100644 sux-spec.ms 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 +$;Hexadecimal Address +%;Binary Address +#[token];Immediate Data Value +[token], ;Zero Matrix, Indexed with X, or Y +([token]);Indirect Addressing +([token], X);Indexed Indirect Addressing +([token]), 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 +.. +.bp +1 +.so intro.ms +.bp +1 +.so base-isa.ms +.bp +1 +.so surp.ms +.TC -- cgit v1.2.3-13-gbd6f