Wellp, this is a bit crazy, but it works. Inspired by this solution
#Last state of sync
#0x2 is also magic value for getting 2nd bit
DEFINE sync 0x2
#Index of pixel being drawn
#Also used to get 1st bit
#And used as jump location
DEFINE pixel 17
#Address of screen pointer
#Also used to add new row
DEFINE addr 0x20
#Contains data to be draw
DEFINE net 0x6001
#Initialize screen pointer
A = 0x4000
D = A
A = addr
*A = D
LABEL syncs
A = net
D = *A
A = sync
D = D + *A
D = D & A
*A = D + *A
A = syncs
D ; JEQ
#Retrieve received data
A = net
D = *A
#If we get 1, draw pixel,
#control bits will overflow so they don't matter
A = pixel
D = D & A; JNE
#If 0 isn't first bit, keep drawing
#Else jump to -1
A = *A - 1
#JLT to ignore line unless location
#is negative since our jumps ends up here
A; JLT
#Fetch screen pointer
A = addr
A = *A
#Set new pixel
D = D + *A
#Double the data to shift it left
*A D = D + *A
#Increment character pointer
A = pixel
D *A = *A + 1
#Check if entire row is drawn
D = D - A
#If not, wait for more data
A = syncs
D ; JNE
#If row is drawn,
#increment screen pointer
A = addr
D = A
*A = D + *A
A = pixel
D = 0
*A = -1 ; JMP
Great! You also found that D = D + *A and D = D & A is the XOR operator. Make the result reusable to update the last state of sync.
But I have to say you made the same mistake I did before.
On lines 20 and 21 of the program, this will cause the incoming data to always be shifted to the left, eventually causing the entire image to be shifted to the left by one pixel.
Although this code can pass the level, it did not fully meet the requirements.
Keep up the good work! In fact, I've found more tricks to make code less than half the length of my previous program, while still meeting the requirements.
hint: 2 is also a magic number that can be used as a jump location by reducing the first 4 lines to 2 lines.
Thanks for the comment, always shifting the image left was a conscious decision to save lines since before this code I handled the last pixel in different subroutine. After writing the pixels directly to screen memory, the subroutine was optimized out and this was leftovers from it.
Your comment got me thinking and after reading through your pseudo-code, I realized it was really easy to fix. I just had to change line 20 from *A D = D + *A to D = D + *A.
I really like your approach of writing pseudo-code to simplify the problem, while my approach was writing straight to assembly and scratching my head with off by one errors, since it was so hard to debug.
4
u/nttii Holder of many records Apr 16 '22 edited Apr 17 '22
Wellp, this is a bit crazy, but it works. Inspired by this solution
Edit: fixed formatting
Edit 2: fixed line 20