The Let's Play Archive

EXAPUNKS

by Carbon dioxide

Part 34: TEC EXA-Blaster™ Modem

Part 34 - TEC EXA-Blaster™ Modem

=== Trash World Inbox ===

Regallion, cardinale and biosterous submitted solutions to the nonogram. Here is cardinale's one, in a pretty shade of blue.



It is an EXA, of course.


=== TEC EXA-Blaster™ Modem ===

You still aren't saying anything in the chat room.
Don't you think they might want to hear from you?




Two votes for "Yeah, but", but "There's nothing to say" barely gets the victory at three votes.

There's nothing for me to say.

I have a theory...
You're enjoying it.
You get to be this mysterious silent presence.
I understand the appeal.


The curse and blessing of a silent protagonist.



[=plastered] bullshit.
[x10x10x] yes
[x10x10x] :)





Ember wants me to mess around with a modem now.

I've collected a lot of data now, but my understanding remains incomplete.



Two votes for the bottom option, and three votes for the winner...

What are you trying to understand, exactly?

Everything.
I need more processing power.
Open networks are getting harder to come by.
Luckily, everyone's buying personal dataphones now.
Thanks, consumer rat race!
Let's get me onto those.


What are you up to now, Ember?


OST: Network Exploration

The assignment:
- Using your modem, connect to each dataphone so that EMBER-2 will have a list of valid phone numbers.
- Each dataphone contains a list of the owner's contacts (file 200). The phone number of one of these dataphones is in your host (file 300), while the rest are in the contact list of another dataphone.
- Note that each dataphone (aside from the first) will appear in exactly one other dataphone's contact list, in such a way that you can find them all without getting stuck in a loop.
- For more information see "Hacker Skills: Modem Control at the Direct Level" in the second issue of the zine.


Alright, let's grab the zine first.



A lot of general information, but the only part that truly matters is that you dial by sending the number to the #DIAL register one digit at a time, and you hang up by sending it a -1.

At a glance, all the numbers in the files seem to be 11 digits long. That'll be helpful.



Just sending the 11 digits from file 300 to #DIAL works to make a connection.

This isn't in the game but feel free to imagine it makes this kind of sound.

The connections always use the 800 and -1 link IDs. And the #DIAL register will ignore any further inputs until you send it a -1.
Importantly, if you have an EXA in a remote host and you hang up, no communication with that EXA is possible. Not even global M communication. That makes a lot of sense, they're truly disconnected hosts now, but it's not something we had to deal with before.

That leaves one part of the assignment that isn't obvious: if each number occurs only once (so you don't get loops), how is it possible that some files have multiple numbers?
Well, by messing around with the modem a bit I found out that those are numbers that aren't accessible from my location. The modem will simply say "connection refused" and hang up.

code:
GRAB 300
LINK 800

MARK NEXT
@REP 11
COPY F #DIAL
@END
REPL M

@REP 11
COPY M F
@END

COPY -1 #DIAL
SEEK -11
JUMP NEXT


MARK M
LINK 800
GRAB 200
SEEK 1
@REP 11
COPY F M
@END
Starting out simple, this EXA dials the one number I know, then the REPL sends back the first number from the remote host and the main EXA dials that one. This works until you get an inaccessible number, at which point the program gets stuck.

So, I need to read all the numbers from the remote hosts (up to four numbers per host). And then dial them one by one, saving new numbers I encounter, while somehow keeping track of which ones I already tried.

I think I have a general idea on how to tackle that. Let's see if it works.

code:
GRAB 300
LINK 800
SUBI X 11 X

MARK NEXT
@REP 11
COPY F #DIAL
@END
REPL M

ADDI X 11 X
NOOP
NOOP
TEST MRD
FJMP NEXT

SEEK 9999
MARK GETNEXT

@REP 11
COPY M F
@END

SUBI X 11 X
NOOP
TEST MRD
TJMP GETNEXT

COPY -1 #DIAL
SEEK X
JUMP NEXT

MARK M
LINK 800
GRAB 200
MARK NEXTNR
SEEK 1
@REP 11
COPY F M
@END
JUMP NEXTNR
The EXA LINKs to the modem. It does some stuff with X which will come into play later. Then it dials the first number, and REPLs to the M EXA.

The M EXA is very simple, it LINKs to the remote host and sends all data over M, only skipping the contact names. It'll die when it reaches the end of the file.

Ignore the main EXA's ADDI X instruction for now - what matters is, it checks if another EXA is sending on M. If so, it copies the whole phone number to the end of its file.

Now it subtracts 11 from X. X contains the value to use in a SEEK instruction to get to the oldest undialed number.
It does another TEST MRD to see if the remote EXA has another number to send, and if so, it stores it too and subtracts another 11 from X.

Once the remote EXA stops, the main one hangs up the modem and SEEKs to X to start dialing the next number. This is where the other X manipulations comes in. Every time it dials a number, it adds 11 to X again so that the index offset to the oldest undialed number is still correct. That's also why I needed the initial SUBI X 11 X, otherwise the value will be off by one phone number for the entire run.

Note that I put the X manipulation in places where I was waiting for MRD anyway. Doesn't cost any extra cycles that way.

This code works in the sense that it connects to every remote host. However, when the main EXA reaches the end of the file and there's no EXAs left sending data, it'll die and drop its file in the modem, which counts as leaving a trace.

That's easily resolved with a cleanup EXA. Add a REPL CLEANUP to the above code, just after the initial LINK 800, and add the following snippet to the bottom.
code:
MARK CLEANUP
COPY 466 T
MARK WAIT
SUBI T 1 T
TJMP WAIT
GRAB 300
WIPE
It's a basic countdown that waits for a while, then GRABs the file and WIPEs it. 466 is the minimal value at which all tests pass.



The top percentiles are 867, 34 and 9. Except for size, I'm closer than I thought. But what improvements are possible?

At first, I thought I could reduce activity by one more. The goal is to connect to each dataphone. Technically I wouldn't need to send an EXA into the last one, since I got all relevant numbers already.
Well, I tried this and it doesn't work. Turns out the tests are coded to only accept the solution if you actually move an EXA into each remote host. So, 9 is the best possible score here.




Moving the cleanup to its own EXA saves a single cycle (in exchange for an activity point). There's a bigger gain by having M send a message immediately as it arrives, before it starts handling the file. It means the top TEST MRD doesn't have to wait as long for it to get ready. 919/65/10.

The EXA that goes into the last remote host still sends all numbers and the main EXA still tries dialing all of them. There's no point in doing so - as soon as there's an EXA in the last host we can stop.

To do so, I rewrote XB to have a counter of how many EXAs reached the foreign hosts:
code:
;XB LOCAL
LINK 800
COPY 8 T

MARK AGAIN
SUBI T M T
TJMP AGAIN

KILL
GRAB 300
WIPE
LINK 800
KILL
Once it hits zero, it KILLs XA, WIPEs the file, and KILLs that one EXA that is still trying to send a number.

XA also needs an addition to make this work. I decided to place it directly after the VOID M, because at that point we know an EXA just reached the remote host - and that EXA is busy grabbing the file so I have a spare cycle or two. Since XB is in local mode, my first thought was to put MODE; COPY 1 M; MODE there but that would delay it by 3 cycles. Instead, I made a special REPL to send the LOCAL message.
code:
;XA GLOBAL

GRAB 300
LINK 800
SUBI X 11 X

MARK NEXT
@REP 11
COPY F #DIAL
@END
REPL M

ADDI X 11 X
TEST MRD
FJMP NEXT
VOID M
REPL MSG

SEEK 9999
MARK GETNEXT

@REP 11
COPY M F
@END

SUBI X 11 X
NOOP
TEST MRD
TJMP GETNEXT

COPY -1 #DIAL
SEEK X
JUMP NEXT

MARK M
LINK 800
COPY 0 M
GRAB 200
MARK NEXTNR
SEEK 1
@REP 11
COPY F M
@END
JUMP NEXTNR

MARK MSG
MODE
COPY 1 M
865/72/13, one cycle below top percentile.

There's a theoretical next improvement, parallellism. That is, if a remote host has multiple phone numbers, I could try dialing the first one immediately, and leave the EXA in the remote host to make a copy of the other phone numbers. Then later I go retrieve them and try dialing them.
This is very complicated though, since the remote EXAs can't just phone home, the main modem one has to dial old hosts again to see if there's an EXA there with additional phone numbers. I suspect it's slower overall, and it might not even fit in the lines of code limit.


Speaking of size, what improvements are possible there? Of course, I can remove the loop unrolls I started with.
code:
GRAB 300
LINK 800
SUBI X 11 X

MARK NEXT
TEST EOF
TJMP WIPE
COPY 11 T
MARK DIALLP
COPY F #DIAL
SUBI T 1 T
TJMP DIALLP
REPL M

ADDI X 11 X
NOOP
TEST MRD
FJMP NEXT

SEEK 9999
MARK GETNEXT
VOID M

COPY 11 T
MARK WRITELP
COPY M F
SUBI T 1 T
TJMP WRITELP

SUBI X 11 X
TEST MRD
TJMP GETNEXT

COPY -1 #DIAL
SEEK X
JUMP NEXT


MARK M
LINK 800
GRAB 200
MARK NEXTNR
COPY F M
JUMP NEXTNR

MARK WIPE
WIPE
I started with my initial working solution and removed all unrolls. The dial loop and write-to-file loop now use a counter to run each 11 times.
The read loop in F has been changed more significantly. I don't skip the contact's name anymore, so that's just a single 3-line non-conditional loop. This requires a VOID M on the writing EXA but that beats adding conditions.
Finally, the cleanup loop was a lot of code so I replaced that with a TEST EOF in the main loop. Slow, but it works. Because the timing is different now I could also remove a couple NOOPs. 1760/38/9.

4 over the top percentile. I'll, uh, leave the remaining improvements as an exercise to the reader.

There's a ton of dataphones out there.
Not very powerful individually, but tied together they work somewhat decently.
I'll just be very... distributed.




You know the drill by now.



[deadlock] hah
[deadlock] if you wanted everyone to leave maybe




There is a knock on the door.



Did you do something with your hair?

Hey. I'm not bothering you am, I?

Isadora looks upset.
Did something happen?

You remember I used to work for Last Stop? Started as a cashier, worked my way up?
I always knew they were close-knit.
But I found out it's much worse than that.
It's a full-on cult.
I don't just mean everyone believes in the company. They believe the whole world isn't real!
They say we're all trapped in some kind of fake reality? I don't know.

Fake reality?
That sounds oddly familiar...
Has someone told me this before?

I wouldn't care if that's all they believed.
The real problem is they think they can force their way out with a big enough explosion.
So they're refining materials to make a bomb... a nuclear bomb.
Right next to piles of old snacks...

Wait, what?
Is she serious?
What is this world?

I have the number for the warehouse where it's all set up.
If I give it to you, you could do something, right?
I need to rest... I'm going to go lie down...


Isadora leaves.

So many questions.
Last Stop... a cult? And her, in the middle of it...?
I just need to take this one moment at a time.
I'll drive myself crazy if I try to figure it all out.


===

Let me see if I understood that correctly.
Last Stop, the convenience store chain, is actually a front for a cult.
They believe the world isn't real, and are in the process of creating a nuclear weapon in order to escape it.
And now you're going to attempt to take care of it yourself, instead of alerting the authorities like a normal person.