On the Subject of 6-Bit Assembly

Thought Markscript was tedious? Check this thing out! Well, at least it has a lot more commands...

This module uses ☼ as prefix of octal values. Every byte is 6 bits and every word is 2 bytes.

This module consists of 3 screens: Data screen, Command screen, Binary screen; and 2 buttons: 0 and 1.

Initially, the data screen shows 64 bytes of the DATA block and also 64 bytes of the COLOR block. COLOR is immutable. If you hover over the symbol in DATA block, the Command screen will show you the word that consists of the DATA byte in higher byte of word and the COLOR byte in lower byte of word.

Pressing the Binary screen will show you the PROG0 block, whopping 64 words of memory for your very own program! That’s not enough for you? Don’t worry! Pressing the Binary screen when the current input is 1 will send you to the other program block, because there’s two of them. There’s also PROG1 - another 64 words of memory!

While seeing PROG0/PROG1, you may input the opcode for a desired command. When you finish inputting the 12-bit string, module will show you the assembly command for your opcode. After that, press 1 to accept the input and insert/replace the command, or 0 to cancel the input. However, if the opcode is not valid, then module will show its octal value with a question mark (for example: ☼3300?).

To go back to DATA, press Binary when the input is empty. To clear the input - press Command. However, if you try to clear the input that is already empty, you will change the insertion mode (INSERT/REPLACE), where the default is REPLACE. To delete the command at the cursor, press Binary when the input is 0. To run the code, press Command when seeing DATA. To stop running, press Command again.

Your goal is to write some code that not only successfully completes the task, but also safely stops the program by going into an infinite loop (the easiest solution for that is RJMP ☼00 in the place where you want to stop the program). Remember that if the CPU goes out of either block or meets an unknown opcode, the module will strike. These are the only 2 cases of the module striking. THE CPU IS NOT GOING TO AUTOMATICALLY JUMP TO PROG1 IF IT GOES BEYOND ☼77 AT PROG0!

Parameters

Everything is zero-indexed in this section.

Take the column at the position of the zeroth vowel in the serial number, otherwise - the zeroth even digit of the serial number, otherwise position 6. From this column, take only the COLOR bytes from top to bottom. The zeroth byte modulo <number of tasks - 1> is the task number. Don’t forget to convert to decimal. The first through the seventh bytes are called the parameters for the task. Going from top to bottom from the first byte, if that byte modulo ☼10 is equal to any previous byte modulo ☼10, then add ☼01 to current byte and modulo it by ☼100. If any parameter is equal to ☼00, add ☼10 to it.

R0-R7 are the registers that store some values, A* refers the address (☼00-☼77), V* means the constant value (☼00-☼77), N* also means some constant, it’s ☼00-☼77 unless stated otherwise. Data[A*] means the byte of DATA at address A*. All values mentioned in a statement are the initial ones (before the program runs), unless stated otherwise. The ranges of bytes wrap around: the byte after ☼77 is ☼00.

*a means that the value is taken from the zeroth parameter, *b - from the first parameter, ..., *g - from the sixth parameter.

To get the variable in its range, modulo it by the number of possible values for this variable and add the smallest possible value for this variable, unless stated otherwise.

Tasks

The number of tasks is 26, the list goes as follows:

Task №Problem Statement
0Rearrange the values of [Ra, Rb, Rc] so that Ra contains the smallest value, Rc - the largest value, Rb - the remaining value.
1Set Rd to the median of [Ra, Rb, Rc].
2Set Rb to the number of Collatz conjecture mod64 steps until Ra gets to 1. In case of an infinite number of steps, set Rb to 63.
3Set Rc to |Ra - Rb|, Rd to (Ra + Rb) mod 64, and Re to 1 if Ra + Rb is even, otherwise to 0.
Task №Problem Statement
4Rotate the 6-bit value of Ra by Nb bits (Nb is 0-5): to the left if Vc is even, to the right if Vc is odd.
5Set Rb to the number of ‘1’ bits in Ra.
6Set Rb to 1 if Ra is a power of two (1, 2, 4, 8, 16 or 32), otherwise set Rb to 0.
7Set Data[Ac] to (Data[Aa] + Data[Ab]) mod 64. Set Rd to 1 if Data[Aa] + Data[Ab] is at least 64 (carry occurred), otherwise to 0.
8If Ra > Rb, swap the values of Ra and Rb. Otherwise, leave them unchanged.
9Set Rc to 1 if Data[Aa] > Vb, to 0 if Data[Aa] = Vb, and to ☼77 (-1) if Data[Aa] < Vb.
10Set Rc to the sum of Nb bytes of DATA starting at Aa, modulo 64.
11Set Rc to the maximum value among Nb bytes of DATA starting at Aa.
12Set Rd to the address of the first byte equal to Vc among Nb bytes of DATA starting at Aa. If there is no such byte, set Rd to ☼77.
13For each Nb byte of DATA starting at Aa: set the byte to Vc if its address is even, or to Vd if its address is odd.
14Reverse the order of bits in each of Nb bytes of DATA starting at Aa (bit 0 ↔ bit 5, bit 1 ↔ bit 4, bit 2 ↔ bit 3).
15Split Nb bytes of DATA starting at Aa into consecutive pairs (1st and 2nd, 3rd and 4th, ...). Set Rc to the sum of |x - y| over all pairs, modulo 64, where x and y are the bytes of a pair. If Nb is odd, the last byte has no pair and is added as is.
16Copy Nb bytes of DATA starting at Aa to Nb bytes starting at Ac in reverse order: the last byte of the source becomes the first byte of the destination, and so on.
17Set Rc to 1 if Nb bytes of DATA starting at Aa are sorted in non-descending order, otherwise to 0. Nb is 2-4.
18Let L be the smaller and H the larger of Vb and Vc. Set Rd to 0 if Ra < L, to 1 if L ≤ Ra ≤ H, and to 2 if Ra > H.
Task №Problem Statement
19Among Nb bytes of DATA starting at Aa, count the local maxima: bytes that are not the first or the last byte of the range and are strictly greater than both of their neighbours. Set Rc to that count. If Nb is less than 3, set Rc to 0.
20Replace each Nb byte of DATA starting at Aa with its remainder of division by Vc.
21Set Rc to the average of Nb bytes of DATA starting at Aa, rounded down. The sum is not reduced modulo 64.
22Add Nc bytes of DATA starting at Ab to Nc bytes starting at Aa element by element (1st to 1st, 2nd to 2nd, ...), modulo 64. The results replace the bytes starting at Aa.
23Set Rc to the number of bytes among Nb bytes of DATA starting at Aa that are strictly greater than the average of those Nb bytes (rounded down). Nb is ☼01-☼77.
24Sort Nb bytes of DATA starting at Aa in non-descending order, in place.
25Shift Nb bytes of DATA starting at Aa one position to the right: each byte moves to the next address, and the byte at Aa becomes Vc. The byte that was last in the range (before the shift) must be saved to Rd. Nb is ☼01-☼77.

Notes on architecture of CPU

Each opcode is 1 word long, no exceptions. P is the value that is stored inside the R7 register and used as address.

Flags are stored inside their own register. There are three flags:

  • Z - Zero flag. Sets when the resulting value equals to ☼00.
  • C - Carry flag. Toggles when the overflow or underflow occurs.
  • N - Negative flag. Sets when the resulting value is more than ☼37.

Opcodes

Translations are based on the AVR Instruction Set.

In the Flags column, uppercase C means setting the flag, lowercase c means toggling the flag. There are 31 commands that are supported by CPU. The list goes as follows:

CommandOpcodeDescriptionFlags
NOP000 000 000 000No operation
Does nothing.
-
MOV Rx, Ry000 000 xxx yyyMove
Copies the value of Ry into Rx.
-
ADD Rx, Ry000 001 xxx yyyAdd
Changes the value of Rx with the sum of values of Rx and Ry.
ZcN
SUB Rx, Ry000 010 xxx yyySubtract
Changes the value of Rx with the value Ry subtracted from the value of Rx.
ZcN
CMP Rx, Ry000 011 xxx yyyCompare
Compares Ry to Rx by subtracting Ry from Rx but not changing any values.
ZcN
AND Rx, Ry000 100 xxx yyyAND
Stores the value of the logical AND of Ry and Rx into Rx.
ZN
OR Rx, Ry 000 101 xxx yyyOR
Stores the value of the logical OR of Ry and Rx into Rx.
ZN
CommandOpcodeDescriptionFlags
EOR Rx, Ry000 110 xxx yyyExclusive OR
Stores the value of the logical XOR of Ry and Rx into Rx.
ZN
NOT Rx000 111 000 xxxNOT
Inverts the value of Rx. In other words, set Rx’s value to (☼77 - Rx’s value).
ZN
LD Rx, P000 111 001 xxxLoad
Loads the value from address P into Rx.
-
ST P, Rx000 111 010 xxxStore
Sets the value from Rx into address P.
-
LSL Rx000 111 011 xxxLogical shift - Left
Shifts Rx to the left. The bit that is shifted out goes in the flag C.
ZC
LSR Rx000 111 100 xxxLogical shift - Right
Shifts Rx to the right. The bit that is shifted out goes in the flag C.
ZC
ROL Rx000 111 101 xxxRotate - Left
Shifts Rx to the left, last bit being set to C, and the bit that is shifted out being stored in the flag C.
ZC
ROR Rx000 111 110 xxxRotate - Right
Shifts Rx to the right, first bit being set to C, and the bit that is shifted out being stored in the flag C.
ZC
RJMP #i001 000 iii iiiRelative jump
Adds #i to Program Counter modulo ☼100. PC does not increment after that.
-
BREQ #i001 001 iii iiiBranch on equal
If flag Z is set, does RJMP #i.
-
BRNE #i001 010 iii iiiBranch on not equal
If flag Z is not set, does RJMP #i.
-
BRCS #i001 011 iii iiiBranch on carry set
If flag C is set, does RJMP #i.
-
BRCC #i001 100 iii iiiBranch on carry clear
If flag C is not set, does RJMP #i.
-
BRMI #i001 101 iii iiiBranch on minus
If flag N is set, does RJMP #i.
-
BRPL #i001 110 iii iiiBranch on plus
If flag N is not set, does RJMP #i.
-
CommandOpcodeDescriptionFlags
JOP addr001 111 aaa aaaJump to other page
Changes the Program Counter to addr, while changing the page to read code from.
-
DJZ Rx, #i010 xxx iii iiiDecrement and jump on zero
Decrements Rx, if Rx equals to 0 after that, does RJMP #i.
-
LDI Rx, #i 100 0xx iii iiiLoad immediate
Loads #i into Rx. Rx is R4-R7.
-
ADDI Rx, #i100 1xx iii iiiAdd immediate
Adds #i to Rx. Rx is R4-R7.
ZcN
SUBI Rx, #i101 0xx iii iiiSubtract immediate
Subtracts #i from Rx. Rx is R4-R7.
ZcN
CMPI Rx, #i101 1xx iii iiiCompare immediate
Compares #i with Rx, similarly to CMP. Rx is R4-R7.
ZcN
ANDI Rx, #i110 0xx iii iiiAND immediate
Does the logical AND of #i and Rx. Rx is R4-R7.
ZN
ORI Rx, #i 110 1xx iii iiiOR immediate
Does the logical OR of #i and Rx. Rx is R4-R7.
ZN
EORI Rx, #i111 0xx iii iiiExclusive OR immediate
Does the logical XOR of #i and Rx. Rx is R4-R7.
ZN

Color and character references

COLORS
01234567
0
1
2
3
4
5
6
7
CHARS
01234567
0_abcdefg
101234567
289.,!@#$
3ABCDEFGH
4IJKLMNOP
5QRSTUVWX
6YZ^&*-+=
7~?<>[]()