You've already found how to write to it. To read from it, use the single-argument form of set instead of the non-working embedded-$-form:
# set with a single argument does a read
puts [set ${asd}(direct)]
The other didn't work because ${…} is a syntactic form that doesn't interpret the bit inside the braces at all (except to look for :: and (…), as those are part of variable names).
However, you should probably use upvar 0 to make a variable alias instead:
set asd pll
upvar 0 $asd ary
# Now we can use simple access syntax
set ary(direct) input
puts $ary(direct)
# Show that it has worked for real...
parray pll
This works more nicely when you're in a procedure because then the alias only lasts until the procedure finishes. Otherwise, the only operation you can do on the alias without altering the underlying variable is to retarget the alias to point to a different variable. (When you do upvar 1, the same mechanism is used. It just looks the aliased variable up in a different stack frame.)