Bitzzy

by Mazzetip

Bitzzy is a LittleBigPlanet3 CPU made by Mazzetip that uses both digital and analog architecture. It has 16-bit addressing, 8-bit registers, is single-core and runs stable up to 10hz.

The CPU is equipped with 3 registers, X, Y and Z. X and Y are general-purpose registers used for receiving, processing and storing data. The Z register is the accumulator, it receives the result from most double-register instructions, such as arithmetic instructions, but this register can also be used like X and Y with no differences.

Interrupts

This CPU is also equipped with an interrupt system that includes IRQ (Interrupt Request Signal) and NMI (Non-Maskable Interrupt) similar to the 6502 CPU.

Both interrupts have their own addresses that tell the CPU where to jump when the NMI or IRQ signals are on.

The IRQ interrupt can be enabled and disabled using instructions in the code. So, when an IRQ is called while it’s disabled, then the interrupt will be forgotten completely, it will not be halted until interrupts are enabled. Also, if interrupts are disabled and an NMI is called, the interrupt will be called anyway, because as the name says: it’s a Non-Maskable Interrupt.

Once an interrupt is called, the CPU will save the current address to the return stack, perform a jump to the location specified and keep running code. The CPU can return from an interrupt with the instruction Return & Return and Restore. It is recommended to use Return and Restore and this one restores the original state of the CPU.

Return Stack

The return stack is a stack used for interrupts and some jump instructions. It not only saves the current Program Counter, it saves the entire state of the CPU, including the Program Counter, X, Y and Z registers, Remainder and Interrupt Enabling.

There are two instructions that pop the return stack, Return & Return and Restore.

Even though Return and Restore is recommended to be used on interrupts, it can also be used in conjunction of “jump & add to return stack” instrucions as a way to restore the registers pre-jump, instead of doing three writes and three reads.

Remainders

Instead of using a carry flag, the CPU uses a remainder system that gives you the result of any math the CPU makes. If you add $80 (128 in decimal) on the X register and $A0 (160 in decimal) on the Y register, the result will be above the 8-bit limit (288) so, the CPU will return to the Z register the value $20 (32 in decimal) and on the remainder, $01. This also means, any multiplication will return a 16-bit number, split between the 8-bit remainder and the used 8-bit register. If you multiply $45 (69 in decimal) and $C0 (192 in decimal) the result will be $C0 on the returned register and $33 (51 in decimal) on the remainder. Keep in mind, that even incrementing/decrementing values also use this register, and when you do any kind of math that doesn’t reach the 8-bit limit, the remainder still will be reset. If you need to use a previous value of the remainder for something, you can copy the remainder to a register and store it or use it as a register.

Software

As a test of the CPU, Bitzzy has been used along with a terminal note display to execute an (inspired) version of Wozmon, which had beautified features like a welcome message, READY and ERROR messages. You could read, write and execute machine code.

TODO: Find vid.

ISA

Bitzzy is an 8-bit CPU, and so the limit of total instructions in a single byte are 256, however this CPU only uses 152 of those 256, but these instructions were chosen to make execution of code quicker on the relatively slow speed of 10hz, using some relatively-specific instructions spreaded across the instruction set.

Upper bits → Lower bits ↓$0$1$2$3$4$5$6$7$8$9$A$B$C$D$E$F
$0$00 HLT$10 JMP <addr>$20 JMPEZ X, <addr>$30 INC X$40 ADD X, <imm>$50 ADD Y, <imm>$60 ADD Z, <imm>$70 LSL X$80 AND X, Y$90 AND X, <imm>$A0 LOD X, <addr>$B0 LOD Y, <addr>$C0 LOD Z, <addr>$D0 STR <imm>, <addr>$E0 DJNZ X, <addr>$F0 JMPRNZ <addr>
$1$01 RET$11 JMP <addr>, X$21 JMPEZ Z, <addr>$31 INC Y$41 SUB X, <imm>$51 SUB Y, <imm>$61 SUB Z, <imm>$71 LSL Y$81 AND X, Z$91 AND Y, <imm>$A1 LOD X, <addr>, Y$B1 LOD Y, <addr>, X$C1 LOD Z, <addr>, X$D1 STR <imm>, <addr>, X$E1 DJNZ Y, <addr>$F1 JMPREZ <addr>
$2$02 RTS$12 JMP <addr>, Y$22 JMPGT X, Y, <addr>$32 INC Z$42 MUL X, <imm>$52 MUL Y, <imm>$62 MUL Z, <imm>$72 LSL Z$82 AND Y, Z$92 AND Z, <imm>$A2 LOD X, <addr>, Z$B2 LOD Y, <addr>, Z$C2 LOD Z, <addr>, Y$D2 STR <imm>, <addr>, Y$E2 DJNZ Z, <addr>$F2 JMPEQ X, Z, <addr>
$3$03 ENI$13 JMP <addr>, Z$23 JMPEQ X, Y <addr>$33 INC <addr>$43 DIV X, <imm>$53 DIV Y, <imm>$63 DIV Z, <imm>$C3 LOD Z, <addr>, YX$D3 STR <imm>, <addr>, Z$F3 JMPEQ Y, Z, <addr>
$4$04 DSI$14 JSR <addr>$24 JSREZ X, <addr>$34 DEC X$44 ADD X, Y$74 LSR X$84 XOR X, Y$94 OR X, <imm>$A4 STR X, <addr>$B4 STR Y, <addr>$C4 STR Z, <addr>$D4 STR <imm>, <addr>, YX$F4 RETREZ
$5$05 NOP$15 JSR <addr>, X$25 JSREZ Y, <addr>$35 DEC Y$45 ADD X, Z$55 ADD Y, Z$75 LSR Y$85 XOR X, Z$95 OR Y, <imm>$A5 STR X, <addr>, Y$B5 STR Y, <addr>, X$C5 STR Z, <addr>, X$F5 RETRNZ
$6$16 JSR <addr>, Y$26 JSRGT X, Y, <addr>$36 DEC Z$46 SUB X, Y$56 SUB Y, X$66 SUB Z, X$76 LSR Z$86 XOR Y, Z$96 OR Z, <imm>$A6 STR X, <addr>, Z$B6 STR Y, <addr>, Z$C6 STR Z, <addr>, Y
$7$17 JSR <addr>, Z$27 JSREQ X, Y <addr>$37 DEC <addr>$47 SUB X, Z$57 SUB Y, Z$67 SUB Z, Y
$8$08 REM X$18 SWP X, Y$28 LOD X, Y$38 SUB <imm>, X$48 MUL X, Y$78 NOT X$88 OR X, Y$98 XOR X, <imm>
$9$09 REM Y$19 SWP X, Z$29 LOD X, Z$39 SUB <imm>, Y$49 MUL X, Z$59 MUL Y, Z$79 NOT Y$89 OR X, Z$99 XOR Y, <imm>
$A$0A REM Z$2A LOD Y, X$3A SUB <imm>, Z$4A DIV X, Y$5A DIV Y, X$6A DIV Z, X$7A NOT Z$8A OR Y, Z$9A XOR Z, <imm>
$B$0B CLR$1B SWP Y, Z$2B LOD Y, Z$4B DIV X, Z$5B DIV Y, Z$6B DIV Z, Y
$C$2C LOD Z, X$3C DIV <imm>, X$4C MOD X, Y$5C MOD Y, X$6C MOD Z, X$7C LOD X, <imm>$9C MOD X, <imm>
$D$2D LOD Z, Y$3D DIV <imm>, Y$4D MOD X, Z$5D MOD Y, Z$6D MOD Z, Y$7D LOD Y, <imm>$9D MOD Y, <imm>
$E$3E DIV <imm>, Z$7E LOD Z, <imm>$9E MOD Z, <imm>
$F

HLT - Halt CPU

This instruction results in the CPU stopping execution, and only an interrupt can resume it.

AssemblyCyclesBytes
HLT21

RET - Return

Returns from a subroutine.

AssemblyCyclesBytes
RET21

RTS - Return and Restore

Returns from a subroutine and restores the previous state of the CPU.

AssemblyCyclesBytes
RTS21

ENI - Enable Interrupts

Enables interrupts.

AssemblyCyclesBytes
ENI21

DSI - Disable Interrupts

Disables interrupts.

AssemblyCyclesBytes
DSI21

NOP - No Operation

No operation executed, time waster.

AssemblyCyclesBytes
NOP21

REM - Save Remainder

Save remainder to a register.

TypeAssemblyCyclesBytes
To X registerREM X21
To Y registerREM Y21
To Z registerREM Z21

CLR - Clear Remainder

Sets the remainder to zero.

AssemblyCyclesBytes
CLR21

JMP - Jump

Jumps execution to a different address.

TypeAssemblyCyclesBytes
Absolute addressJMP 33
Utilize Jump Table at Absolute+XJMP <addr>, X53
Utilize Jump Table at Absolute+YJMP <addr>, Y53
Utilize Jump Table at Absolute+ZJMP <addr>, Z53

JSR - Jump to Subroutine

Jumps execution to a subroutine, saving the state of the CPU to the return stack.

TypeAssemblyCyclesBytes
Absolute addressJSR 33
Utilize Jump Table at Absolute+XJSR <addr>, X53
Utilize Jump Table at Absolute+YJSR <addr>, Y53
Utilize Jump Table at Absolute+ZJSR <addr>, Z53

SWP - Swap

Swaps registers.

TypeAssemblyCyclesBytes
X and YSWP X, Y21
X and ZSWP X, Z21
Y and ZSWP Y, Z21

JMPEZ - Jump if Equal Zero

Jumps execution to address if register is equal zero.

TypeAssemblyCyclesBytes
Using XJMPEZ X, <addr>2 if false, 3 if true3
Using ZJMPEZ Z, <addr>2 if false, 3 if true3

JMPGT - Jump if Greater Than

Jumps execution to address if register X is greater than Y. (8-bit unsigned)

AssemblyCyclesBytes
JMPGT X, Y, <addr>2 if false, 3 if true3

JMPEQ - Jump if Equal

Jumps execution to address if both registers are equal.

TypeAssemblyCyclesBytes
Using X & YJMPEQ X, Y, <addr>2 if false, 3 if true3
Using X & ZJMPEQ X, Z, <addr>2 if false, 3 if true3
Using Y & ZJMPEQ Y, Z, <addr>2 if false, 3 if true3

JSREZ - Jump to Subroutine if Equal Zero

Jumps execution to address and save to the return stack if register is equal zero.

TypeAssemblyCyclesBytes
Using XJSREZ X, <addr>2 if false, 3 if true3
Using ZJSREZ Z, <addr>2 if false, 3 if true3

JSRGT - Jump to Subroutine if Greater Than

Jumps execution to address and save to the return stack if register X is greater than Y. (8-bit unsigned)

AssemblyCyclesBytes
JSRGT X, Y, <addr>2 if false, 3 if true3

JSREQ - Jump to Subroutine if Equal

Jumps execution to address and save to the return stack if X and Y.

AssemblyCyclesBytes
JSREQ X, Y, <addr>2 if false, 3 if true3

DJNZ - Decrement And Jump if Not Zero

Decrements register and jumps if the register is now not zero.

TypeAssemblyCyclesBytes
Using XDJNZ X, <addr>2 if false, 3 if true3
Using YDJNZ Y, <addr>2 if false, 3 if true3
Using ZDJNZ Z, <addr>2 if false, 3 if true3

JMPRNZ - Jump if Remainder Not Zero

Jumps execution to a new address if the remainder is not zero.

AssemblyCyclesBytes
JMPRNZ <addr>2 if false, 3 if true3

JMPREZ - Jump if Remainder Equals Zero

Jumps execution to a new address if the remainder is zero.

AssemblyCyclesBytes
JMPREZ <addr>2 if false, 3 if true3

JMPREZ - Return if Remainder Equals Zero

Returns from a subroutine if the remainder is zero.

AssemblyCyclesBytes
RETREZ <addr>2 if false, 3 if true3

JMPRNZ - Return if Remainder Not Zero

Returns from a subroutine if the remainder is not zero.

AssemblyCyclesBytes
RETRNZ <addr>2 if false, 3 if true3

LOD - Load

Loads a value from a register or address to another register.

TypeAssemblyCyclesBytes
X to YLOD X, Y21
X to ZLOD X, Z21
Y to XLOD Y, X21
Y to ZLOD Y, Z21
Z to XLOD Z, X21
Z to YLOD Z, Y21
Immediate to XLOD X, <imm>22
Immediate to YLOD Y, <imm>22
Immediate to ZLOD Z, <imm>22
Address to XLOD X, <addr>43
Address+Y to XLOD X, <addr>, Y43
Address+Z to XLOD X, <addr>, Z43
Address to YLOD Y, <addr>43
Address+X to YLOD Y, <addr>, X43
Address+Z to YLOD Y, <addr>, Z43
Address to ZLOD Z, <addr>43
Address+X to ZLOD Z, <addr>, X43
Address+Y to ZLOD Z, <addr>, Y43
Address+Y as upper 8 bits+X as lower 8 bits to ZLOD Z, <addr>, YX43

STR - Store

Stores a value from a register to an address.

TypeAssemblyCyclesBytes
Immediate to AddressSTR <imm>, <addr>54
Immediate to Address+XSTR <imm>, <addr>, X54
Immediate to Address+YSTR <imm>, <addr>, Y54
Immediate to Address+ZSTR <imm>, <addr>, Z54
Immediate to Address+Y as upper 8 bits+X as lower 8 bitsSTR <imm>, <addr>, YX54
X to AddressSTR X, <addr>43
X to Address+YSTR X, <addr>, Y43
X to Address+ZSTR X, <addr>, Z43
Y to AddressSTR Y, <addr>43
Y to Address+XSTR Y, <addr>,X43
Y to Address+ZSTR Y, <addr>,Z43
Z to AddressSTR Z, <addr>43
Z to Address+XSTR Z, <addr>,X43
Z to Address+ZSTR Z, <addr>,Y43

INC - Increment

Increment register or address by one.

TypeAssemblyCyclesBytes
To XINC X21
To YINC Y21
To ZINC Z21
To AddressINC <addr>51

DEC - Decrement

Decrement register or address by one.

TypeAssemblyCyclesBytes
To XDEC X21
To YDEC Y21
To ZDEC Z21
To AddressDEC <addr>51

ADD - Addition

Performs addition on an register and/or immediate. Remainder will be 1 when overflowed.

TypeAssemblyCyclesBytes
X + ImmediateADD X, <imm>22
Y + ImmediateADD Y, <imm>22
Z + ImmediateADD Z, <imm>22
X + YADD X, Y21
X + ZADD X, Z21
Y + ZADD Y, Z21

SUB - Substraction

Performs substraction on an register and/or immediate. Remainder will be 1 when underflowed.

TypeAssemblyCyclesBytes
X - ImmediateSUB X, <imm>22
Y - ImmediateSUB Y, <imm>22
Z - ImmediateSUB Z, <imm>22
Immediate - XSUB <imm>, X22
Immediate - YSUB <imm>, Y22
Immediate - ZSUB <imm>, Z22
X - YSUB X, Y21
X - ZSUB X, Z21
Y - XSUB Y, X21
Y - ZSUB Y, Z21
Z - XSUB Z, X21
Z - YSUB Z, Y21

MUL - Multiplication

Performs multiplication on an register and/or immediate. Remainder will be set as the upper 8 bits of the multiplication.

TypeAssemblyCyclesBytes
X * ImmediateMUL X, <imm>22
Y * ImmediateMUL Y, <imm>22
Z * ImmediateMUL Z, <imm>22
X * YMUL X, Y21
X * ZMUL X, Z21
Y * ZMUL Y, Z21

DIV - Division

Performs division on an register and/or immediate. Remainder will always be set as zero.

TypeAssemblyCyclesBytes
X / ImmediateDIV X, <imm>22
Y / ImmediateDIV Y, <imm>22
Z / ImmediateDIV Z, <imm>22
Immediate / XDIV <imm>, X22
Immediate / YDIV <imm>, Y22
Immediate / ZDIV <imm>, Z22
X / YDIV X, Y21
X / ZDIV X, Z21
Y / XDIV Y, X21
Y / ZDIV Y, Z21
Z / XDIV Z, X21
Z / YDIV Z, Y21

MOD - Modulo

Performs a division on an register and/or immediate and returns the remainder of the division. Remainder will always be set as zero.

TypeAssemblyCyclesBytes
X % ImmediateMOD X, <imm>22
Y % ImmediateMOD Y, <imm>22
Z % ImmediateMOD Z, <imm>22
Immediate % XMOD <imm>, X22
Immediate % YMOD <imm>, Y22
Immediate % ZMOD <imm>, Z22
X % YMOD X, Y21
X % ZMOD X, Z21
Y % XMOD Y, X21
Y % ZMOD Y, Z21
Z % XMOD Z, X21
Z % YMOD Z, Y21

LSL - Left Shift

Left shift a register by one.

TypeAssemblyCyclesBytes
Using XLSL X21
Using YLSL Y21
Using ZLSL Z21

LSR - Right Shift

Right shift a register by one.

TypeAssemblyCyclesBytes
Using XLSR X21
Using YLSR Y21
Using ZLSR Z21

NOT - Logical NOT

Toggle all bits from one to zero, and from zero to one.

TypeAssemblyCyclesBytes
Using XNOT X21
Using YNOT Y21
Using ZNOT Z21

AND - Logical AND

AND two values together.

TypeAssemblyCyclesBytes
X & YAND X, Y21
X & ZAND X, Z21
Y & ZAND Y, Z21
X & ImmediateAND X, <imm>22
Y & ImmediateAND Y, <imm>22
Z & ImmediateAND Z, <imm>22

OR - Logical OR

OR two values together.

TypeAssemblyCyclesBytes
X & YOR X, Y21
X & ZOR X, Z21
Y & ZOR Y, Z21
X & ImmediateOR X, <imm>22
Y & ImmediateOR Y, <imm>22
Z & ImmediateOR Z, <imm>22

XOR - Logical XOR

XOR two values together.

TypeAssemblyCyclesBytes
X & YXOR X, Y21
X & ZXOR X, Z21
Y & ZXOR Y, Z21
X & ImmediateXOR X, <imm>22
Y & ImmediateXOR Y, <imm>22
Z & ImmediateXOR Z, <imm>22