Part 25: Sawayama WonderDisc
Part 25 - Sawayama WonderDisc=== Trash World Inbox ===
silentsnack posted:
274/16/548. Each input/output pair is separated by 4, 6, or 8 jumps (sending output at 2 doesn't work because the P-HND signal also hits M-HND) and to make the cycle hit all 3 inputs without saturating we have to rely on the 5 jumps between M-CNS and H-HND, then it can also go one further to P-HNDcode:
LINK 800 COPY -3 X MARK INPUT LINK X LINK X COPY #NERV T MULI X -1 X LINK X LINK X MARK OUTPUT LINK X REPL INPUT LINK X REPL OUTPUT COPY T #NERV JUMP INPUT
As for speed:
silentsnack posted:
Here we can do some shenanigans that rely on something from the zine: "nerve voltages oscillate around -70mV but can spike up to 50 or down to -120" but here if we look at the testdata M shows all the characteristics but I think this is the first time we've seen sensory nerves like H and P that always stay near -70. Why is that useful? It means they're all 2-digit numbers and always have the same sign, but EXAs can handle 4-digit variables, at which point you can probably guess where this is going...
25/39/47 if we comment out the NOOPs and just assume the EXAs start moving in order of XA,XB,XCcode:
;XA LINK 800 LINK -3 LINK -3 MARK M_LOOP REPL NERV JUMP M_LOOP MARK NERV COPY #NERV X COPY #NERV T @REP 4 LINK 3 @END COPY X #NERV COPY T #NERV ;XB ;NOOP LINK 800 LINK 3 LINK 3 LINK 3 REPL HND_LOOP LINK 3 MARK HND_LOOP REPL NERV JUMP HND_LOOP MARK NERV MULI #NERV 100 X ADDI X #NERV M ;XC ;NOOP ;NOOP LINK 800 LINK -3 LINK -3 LINK -3 REPL CNS_LOOP LINK -3 MARK CNS_LOOP NOOP REPL CNS_LOOP COPY M X SWIZ X 43 #NERV;DIV 100 SWIZ X 21 #NERV;MOD -100
About my 37 cycle solution:
GuavaMoment posted:
Very easy to tweak this to save two cycles - have XA do a file copy of 7 length instead of 14, replicate an exa to do it again, and transfer 7 digits over at a time. It's a little faster because now you have two exas who can read and copy values at the same time instead of one doing everything. 35/56/21
There was also an interesting discussion in the thread about learning from each other's solutions. Yes, I've been doing that during this LP as well, many of your ideas went into later puzzle solutions. I don't remember all your ideas nor do I know how to apply some of them in specific situations, but it has helped me come up with better solutions overall.
=== Sawayama WonderDisc - Drive Controller ===
Last time, I fixed my hand.
Do you ever feel like it's a losing battle?
This constant effort to maintain your physical body.
One vote for "stay in the moment", and if I interpreted the votes correctly, three for "everyone eventually loses".
Everyone eventually loses.
I wonder if I'm the same way.
Only time will tell.
Ah, yes, definitely the music industry. I had nothing to do with this.
So, to play that game Isadora got me, I'll need to disable the region lock on the Sawayama.
WonderDisc games are restricted by region locks.
Why?
Two votes for "business reasons" and also two for "big corporations". Time to get out the two-sided die again.
Business reasons, I guess.
Artificial scarcity?
You wouldn't want gamers importing titles too easily.
The less effort it takes, the less special it is.
Hmm.
OST: Getting Started
Let's see what I have to do.
- Modify your WonderDisc, which normally only plays SSEA region games, to play games from any region.
- The SSEA region code is available in file 300.
- It is not necessary to leave no trace. Your EXAs should be written to operate indefinitely.
- For more information see "Hardware Hacks: Sawayama WonderDisc" in the second issue of the zine.
Okay, so make a copy of whatever it needs from the disc but overwrite its region code. But first I need to unlock the system using that key in the zine.
Let's start with that then, so I can see what I'm dealing with.
code:
LINK 800
COPY 8 #AUTH
COPY 0 #AUTH
COPY 3 #AUTH
COPY 2 #AUTH
COPY 7 #AUTH
COPY 1 #AUTH
COPY 0 #AUTH
COPY 4 #AUTH
COPY 9 #AUTH
COPY 5 #AUTH
COPY 1 #AUTH
COPY 2 #AUTH
COPY 5 #AUTH
COPY 2 #AUTH
COPY 6 #AUTH
The key gets filled in on that display in the DISC host, and... I'm in.
A whole lot of track files. Remember, the little lock icon after the file id means you can't move or change them (which makes sense for read-only game discs). The files contain four-digit numbers, with the region code interspersed. I have to find the right track, make a copy in the buffer host with the updated region code, and repeat.
I am going to need the M register no matter what, because copying a file with a single EXA would require dropping it and picking up the copy repeatedly. So let's just get the data to the BUFFER host directly.
Replacing the region code is a bit tricky because it requires fiddling with the limited set of EXA registers. I'll first get the file copy code itself working. After unlocking the disc:
code:
MARK NEXT
REPL WRITER
COPY #TRAK X
LINK 801
GRAB X
MARK RDLOOP
COPY F M
JUMP RDLOOP
MARK WRITER
LINK 800
MAKE
MARK WRLOOP
COPY M F
NOOP
TEST MRD
TJMP WRLOOP
MARK END
DROP
LINK -1
JUMP NEXT
As soon as a file is dropped in the BUFFER, this unusual black EXA comes out of the Reality Processor, grabs the file, and takes it in. The processor notices the file has the wrong region and it'll throw an error.
But... that makes me wonder, can I mess with that black EXA and just take over entirely?
Turns out you can kill it, but this fails the assignment.
Doing so nets us the DISC_READ_ERROR steam achievement, with description "It was just doing its job...". Now I'm feeling bad.
Anyway, the final thing I need to do is overwrite the region code. Now, I considered doing that while copying the file. But that's hard. You can't check directly against M because that will "use up" M. Using X as an intermediate won't work either, because I need a place to store the new region code. And I can't use T because I need to test if a value needs replacing. Let's instead go through the file a second time to change the code.
Ignore that useless HOST command, I just wanted to know what that host was called.
To save a cycle, XB reads the region code into M and XA stores that into X once the disc is unlocked. Once the writer is done, it will REPL a new reader/writer, while it holds on to the file and overwrites the region code with the new one in X. Note that TEST F > -9999 can be used to test if something is text. This test will be true for any valid number (except -9999 but that doesn't occur in these files), but comparisons between text and numbers always return false.
Let's run it.
Hm. Looks like when a small file follows a big file, the small file is sometimes processed before the big one, and the Sawayama doesn't like getting tracks out of order.
An easy fix would be to only handle one file at one but I don't want to slow the code down that much. You know, I'm basically using F as an intermediate register now, can't I inline the region update anyway?
code:
;XA
LINK 800
COPY 8 #AUTH
COPY 0 #AUTH
COPY 3 #AUTH
COPY 2 #AUTH
COPY 7 #AUTH
COPY 1 #AUTH
COPY 0 #AUTH
COPY 4 #AUTH
COPY 9 #AUTH
COPY 5 #AUTH
COPY 1 #AUTH
COPY 2 #AUTH
COPY 5 #AUTH
COPY 2 #AUTH
COPY 6 #AUTH
COPY M X
LINK 800
MARK NEXT
LINK -1
REPL WRITER
COPY #TRAK X
LINK 801
GRAB X
MARK RDLOOP
COPY F M
JUMP RDLOOP
MARK WRITER
LINK 800
MAKE
MARK WRLOOP
COPY M F
SEEK -1
TEST F > -9999
FJMP OVERWRITE
TEST MRD
TJMP WRLOOP
DROP
JUMP NEXT
MARK OVERWRITE
SEEK -1
COPY X F
TEST MRD
TJMP WRLOOP
DROP
JUMP NEXT
;XB
GRAB 300
COPY F M
At 6487/48/94 the solution is rather slow. The top percentiles are 3293, 44 and 3. What's interesting is how far the tenth percentiles are from those numbers: 5584 for cycles and 63 for activity. This shows less people got an actual top score, so optimizing is getting much more difficult.
Anyway, I'm not that far from the low size top score.
To get to 45 I can replace the duplicate TEST MRD code with a jump, and then move the OVERWRITE elsewhere so the EXA dies by reaching the end of the code. If I do that, I can replace the DROP/JUMP with a REPL.
code:
;XA
LINK 800
; AUTH CODE
COPY M X
LINK 800
MARK NEXT
LINK -1
REPL WRITER
COPY #TRAK X
LINK 801
GRAB X
MARK RDLOOP
COPY F M
JUMP RDLOOP
MARK OVERWRITE
SEEK -1
COPY X F
JUMP BACK
MARK WRITER
LINK 800
MAKE
MARK WRLOOP
COPY M F
SEEK -1
TEST F > -9999
FJMP OVERWRITE
MARK BACK
TEST MRD
TJMP WRLOOP
REPL NEXT
Wait a second, now that the OVERWRITE is a jump and then a jump back, can't I inline that too and just skip if no overwrite is necessary?
code:
MARK WRLOOP
COPY M F
SEEK -1
TEST F > -9999
TJMP SKIPOVERWRITE
SEEK -1
COPY X F
MARK SKIPOVERWRITE
TEST MRD
TJMP WRLOOP
REPL NEXT
I don't think I can lower the size much more, so let's focus on the cycle count. Unrolls!
There's no point unrolling the reader by itself because the writer needs to do all the checks and is slower anyway. The files seem to be between 6 and 36 entries in size, always a multiple of 6. I can use that but unrolls in combination with jumps (for the overwrite) are always complex.
This solution uses the advanced REP syntax. The @{0,1} means "fill in zero for the first repetition, then 1 for the next, and keep incrementing by one." So I have a MARK SKIPOVERWRITE0, MARK SKIPOVERWRITE1 and so on in the unrolled result. This way, with the jumps it doesn't lose its place in the unroll, so no matter what, it checks for MRD every 6 repetitions. 4799/77/64.
For my next improvement I have a completely different idea. Can I parallellize the file copying? That requires the M register which is quite occupied... except we also have LOCAL mode.
You might think that won't fit in the DISC host but it does. One EXA in global mode can grab a file. Then a second EXA in local mode can grab a second file, and then a third one can use the one empty spot in the DISC to make a new file. I had some code that seemed like it would work but it got stuck when the Sawayama requested the same track twice in a row and the slowest EXA couldn't find it because the fastest was holding it.
I went through several complete rewrites before ending up with something that actually works.
It still isn't close to the top percentile but honestly, after being at it for several hours I consider this Good Enough. I'll start with XB, which has two purposes. The top half:
code:
;XB LOCAL
GRAB 300
COPY F X
DROP
LINK 800
REPL WRITER
MAKE
COPY #TRAK F
MARK ROUND
COPY #TRAK F
SEEK -2
TEST F = F
SEEK -2
COPY F M
TJMP SKIPLOCAL
COPY F M
COPY X M
COPY #TRAK F
JUMP ROUND
MARK SKIPLOCAL
COPY 0 M
SEEK 1
JUMP ROUND
code:
;XB cont'd
MARK WRITER
MODE
LINK 800
MARK WRITEFILE
MAKE
MARK WRLOOP
COPY M F
SEEK -1
TEST F > -9999
TJMP SKIPOVERWRITE
SEEK -1
COPY X F
MARK SKIPOVERWRITE
TEST MRD
TJMP WRLOOP
DROP
MODE
VOID M
MODE
JUMP WRITEFILE
code:
;XA LOCAL
LINK 800
COPY 8 #AUTH
COPY 0 #AUTH
COPY 3 #AUTH
COPY 2 #AUTH
COPY 7 #AUTH
COPY 1 #AUTH
COPY 0 #AUTH
COPY 4 #AUTH
COPY 9 #AUTH
COPY 5 #AUTH
COPY 1 #AUTH
COPY 2 #AUTH
COPY 5 #AUTH
COPY 2 #AUTH
COPY 6 #AUTH
MARK ROUND
COPY M X
REPL GLOBALREADER
COPY M T
TJMP LOCALRW
LINK 800
COPY 0 M
LINK -1
JUMP ROUND
code:
;XA cont'd
MARK GLOBALREADER
MODE
LINK 801
GRAB X
MARK RDLOOP
COPY F M
JUMP RDLOOP
code:
;XA cont'd
MARK LOCALRW
COPY M X
LINK 801
GRAB T
REPL LOCALWRI
JUMP RDLOOP
MARK LOCALWRI
MAKE
MARK LOCALWRLOOP
COPY M F
SEEK -1
TEST F > -9999
TJMP SKIPOVERWRITE
SEEK -1
COPY X F
MARK SKIPOVERWRITE
TEST MRD
TJMP LOCALWRLOOP
code:
;XA cont'd
LINK -1
LINK 800
COPY 0 M
DROP
LINK -1
JUMP ROUND
So, to summarize:
- XB checks if two files can be handled at once (different IDs). If so, XA puts them both to work. Once one of them is done, it has to wait for the other so that everything stays in sync.
- If the Sawayama wants the same track twice, only the GLOBAL reader runs, slowing down the process but making sure it stays in sync.
The result is 3830/98/81 and I'm just glad I got a sub-4000 cycle count. There's no space left for unrolls since the max allowed size is 100.
Finally, the 3-activity solution is tricky, but doable.
The issue is that since you can't move EXAs around, the M register has to do a lot of duties at the same time. So I have to be smart about it.
I wrote a solution but didn't bother it optimizing for anything but activity so forgive me for my ugly code.
code:
GRAB 300
COPY F X
DROP
LINK 800
REPL WRITER
COPY 8 #AUTH
COPY 0 #AUTH
COPY 3 #AUTH
COPY 2 #AUTH
COPY 7 #AUTH
COPY 1 #AUTH
COPY 0 #AUTH
COPY 4 #AUTH
COPY 9 #AUTH
COPY 5 #AUTH
COPY 1 #AUTH
COPY 2 #AUTH
COPY 5 #AUTH
COPY 2 #AUTH
COPY 6 #AUTH
REPL READER
MARK TRAK
COPY #TRAK M
COPY 190 T
MARK WAIT
SUBI T 1 T
TJMP WAIT
JUMP TRAK
MARK READER
LINK 801
MARK READNEXT
GRAB M
MARK RDLOOP
COPY F M
TEST EOF
FJMP RDLOOP
DROP
JUMP READNEXT
MARK WRITER
LINK 800
REPL MCONTROLLER
MODE
MARK WRITEFILE
MAKE
MARK WRLOOP
COPY M F
SEEK -1
TEST F = 0
TJMP DONE
SEEK -1
TEST F > -9999
TJMP SKIPOVERWRITE
SEEK -1
COPY X F
MARK SKIPOVERWRITE
JUMP WRLOOP
MARK DONE
SEEK -1
VOID F
DROP
JUMP WRITEFILE
MARK MCONTROLLER
COPY M X
TEST X < 300
TJMP GLOBAL
MODE
COPY X M
MODE
TEST MRD
FJMP NEXTFILE
JUMP MCONTROLLER
MARK GLOBAL
COPY X M
TEST MRD
FJMP NEXTFILE
JUMP MCONTROLLER
MARK NEXTFILE
MODE
COPY 0 M
MODE
JUMP MCONTROLLER
It starts with unlocking the disc like normal, and REPLing a single writer and reader. The reader is still quite simple: grab the file id which is received through M, then send all data through M, but specifically check for EOF and read the next file when it's done.
The tricky part is in the WRITER. It runs in LOCAL mode. There's an M-CONTROLLER EXA that receives all GLOBAL M messages. If it's a number under 300 (a file ID), it sends it on global M again because it was actually intended for the reader but the controller happened to intercept it. If it's anything else, the WRITER needs it, so the MCONTROLLER forwards it in LOCAL mode. Finally, if nobody is sending, the controller sends a 0 to the WRITER to let it know the file is done.
So, how do you tell the EXA reading from #TRAK that it should send a new value? That's the neat part, you don't. If you try it with M, all EXAs will intercept messages from each other and you'll end up in unpredictable inescapable loops. Instead, that EXA just has a very long countdown (190 two-cycle iterations) so it waits long enough for even the biggest file to be done.
The countdown and all M messages having to go through the controller make this solution slow.
That was a lot of work just to play one game.
Think it will be worth it?
And that brings us to our first vote.
Once again, we unlocked a special minigame. This time it isn't Solitaire. It is called HACK*MATCH.
Think the console version will live up to the arcade classic?
Here's the second vote. We'll check out the minigame next time.