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 ☼## to show its bytes as opposed to $## as usual. 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 as 64 bytes of the COLOR block. COLOR is immutable.

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!

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 insertion mode (INSERT/REPLACE), default being 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 CPU by going into an infinite loop (the easiest solution for that is RJMP ☼00 in the place where you want to finish the program). Remember that if CPU goes out of the either block or meets an unknown opcode, the module will strike. Those are the only 2 cases of module striking. THIS MEANS THAT CPU IS NOT GOING TO AUTOMATICALLY JUMP TO PROG1 IF IT GOES BEYOND ☼77 AT PROG0!

Tasks

Tasks require some parameters. R* means register with some number (R0-R7), A* means address (☼00-☼77), V* means 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. Ranges of bytes wrap around: the byte after ☼77 is ☼00.

*a means that the value is taken from first byte of task info, *b - from second byte, *c - from third, ..., *g - from seventh. Zeroth byte is the task number (0 - <number of tasks - 1>)

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

Parameters are taken from column of position of the first vowel in SN, else position of the first even number in SN, else position 7. Going from top to bottom, if a parameter modulo 8 is equal to any previous parameter modulo 8, then add 1 to the parameter and modulo it by 64. If any parameter except the 0th is equal to 0, add 8 to it.

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.
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.
Task №Problem Statement
14Reverse the order of bits in each Nb byte 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.
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. Vc is ☼01-☼77.
21Set Rc to the average of Nb bytes of DATA starting at Aa, rounded down. The sum is not reduced modulo 64. Nb is ☼01-☼77.
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.

Opcodes

Each opcode is 1 word long, no exceptions. When you’ll try to input the 12 bits of a word in any of the PROG blocks, the module will show the readable assembly function. However, if the opcode is not valid, then module will show its octal value with a question mark (for example: ☼3300?). Press 1 to accept the input and 0 to reset it.

Address Z is the R7 value. 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 000Does nothing.-
MOV Rd, Rs000 000 ddd sssCopies Rs into Rd.-
ADD Rd, Rs000 001 ddd sssAdds Rs to Rd.ZcN
SUB Rd, Rs000 010 ddd sssSubtracts Rs from Rd.ZcN
CMP Rd, Rs000 011 ddd sssCompares Rs to Rd by subtracting Rs from Rd but not changing the value.ZcN
AND Rd, Rs000 100 ddd sssDoes the logical AND of Rs and Rd.ZN
OR Rd, Rs 000 101 ddd sssDoes the logical OR of Rs and Rd.ZN
XOR Rd, Rs000 110 ddd sssDoes the logical XOR of Rs and Rd.ZN
NOT Rd000 111 000 dddInverts Rd.ZN
LD Rd, Z000 111 001 dddLoads the value from address Z into Rd.-
ST Z, Rd000 111 010 dddSets the value from Rd into address Z.-
LSL Rd000 111 011 dddShifts Rd to the left. Thrown bit goes in flag C.ZC
LSR Rd000 111 100 dddShifts Rd to the right. Thrown bit goes in flag C.ZC
CommandOpcodeDescriptionFlags
ROL Rd000 111 101 dddRotates Rd to the left through flag C.ZC
ROR Rd000 111 110 dddRotates Rd to the right through flag C.ZC
RJMP addr001 000 aaa aaaRelative jump.-
BREQ addr001 001 aaa aaaRelative branch if equal (Z = 1).-
BRNE addr001 010 aaa aaaRelative branch if not equal (Z = 0).-
BRCS addr001 011 aaa aaaRelative branch on carry set (C = 1).-
BRCC addr001 100 aaa aaaRelative branch on carry clear (C = 0).-
BRMI addr001 101 aaa aaaRelative branch if negative (N = 1).-
BRPL addr001 110 aaa aaaRelative branch if positive (N = 0).-
JOP addr001 111 aaa aaaAbsolute jump to other page.-
DJZ Rd, addr010 ddd aaa aaaDecrement Rd, relative jump if zero.-
LDI Rd, #i 100 0dd iii iiiLoad #i into Rd. Rd is R4-R7.-
ADDI Rd, #i100 1dd iii iiiAdd #i to Rd. Rd is R4-R7.ZcN
SUBI Rd, #i101 0dd iii iiiSubtract #i from Rd. Rd is R4-R7.ZcN
CMPI Rd, #i101 1dd iii iiiCompare #i with Rd, similarly to CMP. Rd is R4-R7.ZcN
ANDI Rd, #i110 0dd iii iiiDoes the logical AND of #i and Rd. Rd is R4-R7.ZN
ORI Rd, #i 110 1dd iii iiiDoes the logical OR of #i and Rd. Rd is R4-R7.ZN
XORI Rd, #i111 0dd iii iiiDoes the logical XOR of #i and Rd. Rd is R4-R7.ZN